Intellisense for Vuex Store in VS Code



我正在使用 vuejs2、vuex 和 typescript 在 visual-studio-code 中构建一个应用程序。 我安装了兽医扩展。我已经构建了一个定义文件,为我的大部分项目提供了智能感知,但我无法弄清楚如何将我的 vuex 商店添加到智能感知中。 我已经通读了定义文档,但我无法弄清楚如何做到这一点。 我的目标是能够对this.$store.中的任何事物进行智能感知。 目前,vetur 为stategetters等提供智能感知,但它不提供下一级的智能感知(例如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>

您可以通过显式键入状态来实现此目的。

Contract Management Store.ts

export interface ContractManagementState {
Contract: ContractType;
}

在您的组件中:

...
(this.$store as Store<ContractManagementState>).<intellisense here>

不幸的是,每次以这种方式访问状态时都必须这样做。这是由于 Vuex 使用模块扩充来声明$store属性的存在到打字稿的方式。

vuex/types/vue.d.ts

declare module "vue/types/vue" {
interface Vue {
$store: Store<any>;
}
}

你不能用具体的状态类型覆盖任何(毕竟这称为模块扩充(。一种可能的解决方案是使用 getter 来访问您的商店。存在几个打字稿库,用于向getter,mutators和action添加类型信息,例如vuex-typescript和vuex-typex。

这两天我也遇到了这个问题,无法忍受this.$store.state缺乏打字意识。

@georg-Grab的解决方案给了我这个灵感。

  1. 我不熟悉打字稿...所以这个解决方案可能很愚蠢,但它有效。
  2. 我的解决方案只能处理this.$store.state,所有其他如this.$store.dispatch仍然没有智能感知
// 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)

现在,您可以通过this.$state访问this.$store.state中的值,并使用智能感知。

我也想"覆盖"vm.$store的接口(从Store<any>Store<State>(,但TypeScript似乎没有办法做这样的事情:

declare module 'vue/types/vue' {
interface Vue {
$store: Store<State>   // Error
}
}

最新更新