6

我正在使用在vi​​sual 中构建应用程序。我安装了扩展。我已经为我的大部分项目构建了一个定义文件来为我提供智能感知,但我一直无法弄清楚如何将我的存储添加到智能感知。我已经通读了定义文档,但我无法一起思考如何做到这一点。我的目标是能够在this.$store.. 目前,为 , 等提供智能感知stategetters但不为下一层提供智能感知(例如this.$store.state.TestVariable)。如何为我的商店获取智能感知?

合同管理商店

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>
4

2 回答 2

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(这毕竟称为模块扩充)。一种可能的解决方案是使用 getter 访问您的商店。有几个 typescript 库用于向 getter、mutators 和 action 添加类型信息,例如vuex -typescript和vuex-typex

于 2018-06-01T13:47:52.440 回答
0

这两天我也遇到这个问题,受不了this.$store.state.

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

  1. 我不熟悉 TypeScript ......所以这个解决方案可能很愚蠢,但它确实有效。
  2. 我的解决方案只能处理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.$store.statevia中的值。this.$state

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

declare module 'vue/types/vue' {
  interface Vue {
    $store: Store<State>   // Error
  }
}
于 2018-09-28T03:41:39.343 回答