我正在使用vuejs2中的vuex,typescript和visual-studio-code构建应用程序。我安装了vetur扩展程序。我已经构建了一个定义文件来为我的大多数项目提供intellisense,但是我还没弄清楚如何将我的vuex商店添加到intellisense。我已经阅读了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>
答案 0 :(得分:0)
您可以通过明确键入州来实现这一目标。
在Contract Management Store.ts
export interface ContractManagementState {
Contract: ContractType;
}
在你的组件中:
...
(this.$store as Store<ContractManagementState>).<intellisense here>
不幸的是,每次以这种方式访问状态时都必须这样做。这是由于Vuex使用模块扩充的方式来声明存在$store
属性到typescript。
在vuex/types/vue.d.ts
:
declare module "vue/types/vue" {
interface Vue {
$store: Store<any>;
}
}
你无法用你的具体状态类型覆盖any(毕竟这被称为模块 augmentation )。一种可能的解决方案是使用getter访问您的商店。有几个打字稿库可用于向getter,mutators和actions添加类型信息,例如vuex-typescript和vuex-typex。
答案 1 :(得分:0)
这两天我也遇到了这个问题,无法忍受this.$store.state
缺乏打字意识。
@georg-grab 's solution给了我这个灵感。
- 我对TypeScript不熟悉...因此,这种解决方案可能很愚蠢,但是可以。
- 我的解决方案只能处理
this.$store.state
,而所有其他解决方案,例如this.$sotre.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插件添加全局实例获取器:
// 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.$store.state
访问this.$state
中的值。
我也想“覆盖”
vm.$store
(从Store<any>
到Store<State>
)的接口,但是TypeScript似乎无法做到这一点:declare module 'vue/types/vue' { interface Vue { $store: Store<State> // Error } }