【问题标题】:How is the correct way to work with Vuex and typescript?使用 Vuex 和 typescript 的正确方法是什么?
【发布时间】:2019-05-17 08:26:47
【问题描述】:

到目前为止,我找到的有关该主题的唯一信息是article

我正在尝试使用 2 个模块来实现商店。

export interface RootState {
    /** root state props **/
}

const store: StoreOptions<RootState> = {
    modules: {
        foo,
        bar,
    },
};

export default new Vuex.Store<RootState>(store);

然后我有两个模块:

export interface FooState {
    //(...)    
}

export const foo: Module<FooState, RootState> = {
    //(...)
};

export interface BarState {
    //(...)    
}

export const bar: Module<BarState, RootState> = {
    //(...)
};

一切都还好,直到我遇到需要从 foo 模块获取 getter 来访问 bar 状态的情况:

export const getters: GetterTree<FooState, RootState> = {
    getInfo: (state, {}, rootState) => number {
        const value = rootState.bar.somevalue;
        //(...)
    },
};

我有一个 linting 错误,解释 rootState 没有 bar 属性。经过一段时间的思考,我设法解决了更改原始 RootState 接口的错误:

export interface RootState {
    /** root state props **/
    foo: FooState;
    bar: BarState;
}

它解决了问题,非常适合 IDE 智能感知。

这种方法正确吗?要将所有模块添加到 StoreOptions 使用的 RootState 接口中?

此外,似乎缺乏关于这些类型化接口(StoreOptions、Module、GetterTree 等)的文档:Vuex 是否成熟到可以与 typescript 一起使用?

编辑:我忘了提:当从组件访问存储时,我仍然需要强制转换 this.$store(但可以使用vuex-class 将其最小化)。似乎有一个question 打开了它而没有答案。我想到目前为止还没有其他解决方案,对吗?

【问题讨论】:

  • 在您的编辑中,在vue-shim.d.ts 文件中(假设您有一个)只需将 $store 声明为Store&lt;RootState&gt;
  • @Ohgodwhy 我有一个 shims-vue.d.ts 但我认为它是一样的。我不知道如何在那里更改商店类型。你能给我举个例子吗?到目前为止,我发现的最好的解决方法是:forum.vuejs.org/t/…
  • @Ohgodwhy 这个文件是干什么用的?如何设置店铺类型?
  • 使用 vuex4,你可以像这样访问 getter:this.$store.getters['YourSubModule/yourGetterName']stackoverflow.com/questions/41833424/…

标签: typescript vue.js vuex


【解决方案1】:

Vuex 与使用这些 vuex 导入的 typescript 完美兼容:

import {GetterTree, MutationTree, ActionTree} from "vuex"

下面的例子展示了在 typescript 中使用 vuex 的最简单、最完整的方法。

主存储文件:

import Vue from 'vue'
import Vuex from 'vuex'
import { GetterTree, MutationTree, ActionTree } from "vuex"
import MySubModule from '@/store/submodule'

Vue.use(Vuex)

class State {
    userId: string | null = null;
}

const getters = <GetterTree<State, any>>{
};

const mutations = <MutationTree<State>>{
    setUserId(state, payload) {
        state.userId = payload;
    }
};

const actions = <ActionTree<State, any>>{
    fetchUserId(store) {
    }
};

export default new Vuex.Store({
    state: new State(),
    mutations: mutations,
    actions: actions,
    modules: {
        subModuleName: MySubModule,
        //other submodules
    }
})

子模块存储文件:

import { GetterTree, MutationTree, ActionTree } from "vuex"

class State {
}

const mutations = <MutationTree<State>>{
};

const actions = <ActionTree<State, any>>{
};

const MySubModule = {
    namespaced: true,
    state: new State(),
    mutations: mutations,
    actions: actions
};

export default MySubModule;

希望能帮到你!

【讨论】:

  • 如果您访问export default new Vuex.Store({ ... }) 提供的导出实例,此解决方案将不起作用。 store.state.subModule 抛出错误。
  • 使用 $store.state.subModule 对我来说效果很好。
  • 这个例子不完整。您需要展示如何从组件中实际使用 Vuex 存储。
  • 你为什么用any代替RootState?正确的不应该是GetterTree &lt; State, RootState&gt; ActionTree &lt; State, RootState&gt;?我真的不明白为什么RootState应该是,没有的危险
  • 这个解决方案甚至不是真正的打字稿,因为它一直使用any
猜你喜欢
  • 1970-01-01
  • 2015-03-01
  • 2019-11-11
  • 2018-07-08
  • 2016-11-21
  • 2020-07-10
  • 2018-12-17
  • 2014-12-08
  • 1970-01-01
相关资源
最近更新 更多