使用 Vuex 和 typescript 的正确方法是啥?
Posted
技术标签:
【中文标题】使用 Vuex 和 typescript 的正确方法是啥?【英文标题】: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<RootState>
。
@Ohgodwhy 我有一个 shims-vue.d.ts 但我认为它是一样的。我不知道如何在那里更改商店类型。你能给我举个例子吗?到目前为止,我发现的最好的解决方法是:forum.vuejs.org/t/…
@Ohgodwhy 这个文件是干什么用的?如何设置店铺类型?
使用 vuex4,你可以像这样访问 getter:this.$store.getters['YourSubModule/yourGetterName']
***.com/questions/41833424/…
【参考方案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 < State, RootState>
ActionTree < State, RootState>
?我真的不明白为什么RootState
应该是,没有的危险
这个解决方案甚至不是真正的打字稿,因为它一直使用any
以上是关于使用 Vuex 和 typescript 的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 vuex 和 typescript 将 axios 调用移动到自己的方法中
问:使用 Vue 3 和 typescript(使用 cli 构建的项目)使 vuex 存储在全球范围内可用 +已解决
Typescript Vuex - 如何使用 setter 和 getter 定义状态?
在 Vue 3 中使用 Vuex 4 模块和 TypeScript,以及如何修复循环依赖 linting 错误?