【问题标题】:Intellisense for Vuex Store in VS CodeVS Code 中 Vuex Store 的 Intellisense
【发布时间】:2018-11-11 15:07:13
【问题描述】:

我正在使用 中构建应用程序。我安装了 扩展。我已经为我的大部分项目构建了一个定义文件来为我提供智能感知,但我无法弄清楚如何将我的 存储添加到智能感知。我已经阅读了Definition Documentation,但我无法一起思考如何做到这一点。我的目标是能够对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>

【问题讨论】:

    标签: vuejs2 vuex typescript visual-studio-code vetur vuex vetur vuex typescript visual-studio-code vuejs2 vuex vetur


    【解决方案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-typescriptvuex-typex

    【讨论】:

    • 我不同意你关于使用吸气剂作为最佳实践的观点。阅读documentation 我看到商店被直接访问以读取数据。我相信最佳实践更侧重于通过我在代码中正确使用的突变/操作来修改数据。你有任何关于始终使用 getter 访问状态的 Vuex 文档吗?
    • 我可以从中获得智能感知状态...我将如何修改它以获取 getter/mutators/actions 的智能感知?
    • 你说得对,Vuex 文档中没有明确建议 getter 直接访问状态。我已经编辑了我的答案,所以我的意见听起来不像是官方推荐。我仍然认为关于调试和解耦的观点是有效的。此外,谈到您的第二条评论,让 getter 更适合打字稿。我建议查看我在答案中发布的库,它还允许您键入 mutators 和操作(以一些开销代码为代价)
    【解决方案2】:

    这两天我也遇到这个问题,受不了this.$store.state的打字意识的缺失。

    @georg-grab 's solution 给了我这个灵感。

    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.$state 访问this.$store.state 中的值。

    我也想“覆盖”vm.$store的接口(从Store&lt;any&gt;Store&lt;State&gt;),但是TypeScript似乎没有办法做这样的事情:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-19
      • 2020-06-23
      • 1970-01-01
      • 2019-09-15
      • 1970-01-01
      • 2018-01-17
      • 2019-08-04
      • 1970-01-01
      相关资源
      最近更新 更多