VS Code 中 Vuex Store 的 Intellisense
Posted
技术标签:
【中文标题】VS Code 中 Vuex Store 的 Intellisense【英文标题】:Intellisense for Vuex Store in VS Code 【发布时间】:2018-11-11 15:07:13 【问题描述】:我正在使用vuejs2、vuex 和typescript 在visual-studio-code 中构建应用程序。我安装了vetur 扩展。我已经为我的大部分项目构建了一个定义文件来为我提供智能感知,但我无法弄清楚如何将我的 vuex 存储添加到智能感知。我已经阅读了Definition Documentation,但我无法一起思考如何做到这一点。我的目标是能够对this.$store.
中的任何内容进行智能感知。目前,vetur 为state
、getters
等提供智能感知,但不为下一级(例如this.$store.state.TestVariable
)提供智能感知。如何为我的vuex 商店获取智能感知?
合同管理商店
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store(
state:
Contract: new Library.Model.Entity.Contract()
);
合约组件
<template>
<contract-line></contract-line>
</template>
<script lang="ts">
import Vue from 'vue';
import Vuex from 'vuex';
import store from '../store/ContractManagementStore';
import ContractLine from "./ContractLine.vue";
export default Vue.extend(
name: 'contract-management',
store,
components:
'contract-line': ContractLine
);
</script>
<style>
</style>
合同线组件
<template>
<button v-if="CanDelete"></button>
</template>
<script lang="ts">
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default Vue.extend(
computed:
CanDelete(): Boolean
// Looking for intellisense after this.$store.state.
return this.$store.state.Contract.ContractStatus.Value === Library.Enums.ContractStatus.Draft
);
</script>
<style>
</style>
【问题讨论】:
【参考方案1】:您可以通过显式输入您的状态来实现此目的。
在Contract Management Store.ts
export interface ContractManagementState
Contract: ContractType;
在您的组件中:
...
(this.$store as Store<ContractManagementState>).<intellisense here>
不幸的是,每次以这种方式访问状态时,您都必须这样做。这是由于 Vuex 使用模块扩充的方式来向 typescript 声明 $store
属性的存在。
在vuex/types/vue.d.ts
:
declare module "vue/types/vue"
interface Vue
$store: Store<any>;
你不能用你的具体状态类型覆盖 any(毕竟这被称为模块 augmentation)。一种可能的解决方案是使用 getter 访问您的商店。有几个 typescript 库用于向 getter、mutators 和 action 添加类型信息,例如 vuex-typescript 和 vuex-typex。
【讨论】:
我不同意你关于使用吸气剂作为最佳实践的观点。阅读documentation 我看到商店被直接访问以读取数据。我相信最佳实践更侧重于通过我在代码中正确使用的突变/操作来修改数据。你有任何关于始终使用 getter 访问状态的 Vuex 文档吗? 我可以从中获得智能感知状态...我将如何修改它以获取 getter/mutators/actions 的智能感知? 你说得对,Vuex 文档中没有明确建议 getter 直接访问状态。我已经编辑了我的答案,所以我的意见听起来不像是官方推荐。我仍然认为关于调试和解耦的观点是有效的。此外,谈到您的第二条评论,让 getter 更适合打字稿。我建议查看我在答案中发布的库,它还允许您键入 mutators 和操作(以一些开销代码为代价)【参考方案2】:这两天我也遇到这个问题,受不了this.$store.state
的打字意识的缺失。
@georg-grab 's solution 给了我这个灵感。
我对 TypeScript 不熟悉...所以这个解决方案可能很傻,但它确实有效。 我的解决方案只能处理
this.$store.state
,其他的如this.$store.dispatch
仍然没有IntelliSense
// store/index.ts
// I will not explain vuex modules here. Please see the doc of Vuex by yourself.
import Vue from 'vue'
import Vuex, Store from 'vuex'
import auth, State as AuthState from './modules/auth' // State is an interface defined in module.
export interface State
auth: AuthState
Vue.use(Vuex)
export default new Vuex.Store(
modules:
auth
) as Store<State> // Force TypeScript compiler to recognize this as Store<State> instead of Store<any>.
然后通过 Vue 插件添加一个全局实例 getter:
// main.ts
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store, State from './store'
declare module 'vue/types/vue' // Tell TypeScript the type of this.$state is our defined 'State'
interface Vue
$state: State
const TypedState = // define a Vue plugin. See https://vuejs.org/v2/guide/plugins.html
install(Vue: any) // For simplify, didn't pass 'State' via options
Object.defineProperty(Vue.prototype, '$state', // Add a global getter 'this.$state' in vm
get (): State return store.state as State // Force TypeScript compiler to recognize this as our defined 'State'
)
Vue.use(TypedState)
现在您可以使用 IntelliSense 通过this.$state
访问this.$store.state
中的值。
我也想“覆盖”
vm.$store
的接口(从Store<any>
到Store<State>
),但是TypeScript似乎没有办法做这样的事情:declare module 'vue/types/vue' interface Vue $store: Store<State> // Error
【讨论】:
以上是关于VS Code 中 Vuex Store 的 Intellisense的主要内容,如果未能解决你的问题,请参考以下文章