为vuex中store添加类型检测的问题

69 阅读2分钟

上述代码中,想要从vuex中取出用户菜单信息,userMenus显示类型为any。这样一来就无法利用TypeScript来实现类型检测,不利于提高代码的鲁棒性。

因此,结合网络上教程,分享一种可以为vuex的store提供类型检测的方法。

在项目store文件夹下的types.ts文件中写入下列代码。最终导出的联合类型IStoreType就可以提供给useStore来使用。此外,当要使用其他vuex子模块的状态时,只需要引入对应的状态,并在IRootWithModule中添加对应的类型即可。

import { ILoginState } from './login/types'
export interface IRootState {
  name: string
  age: number
}

export interface IRootWithModule {
  login: ILoginState
}
export type IStoreType = ILoginState & IRootWithModule

其中引入的'./login/types'具体内容如下

export interface ILoginState {
  token: string
  userInfo: any
  userMenus: any
}

定义好IStoreType之后,就可以在/store/index.ts中进行使用。代码对useStore进行返回。我们在之后其他组件中需要取store时,不是直接引用vuex的useStore,而是使用这里自己定义的stote中的useStore。

import { createStore, Store, useStore as useVuexStore } from 'vuex'
import { IRootState, IStoreType } from './types'

import login from './login/login'
//createStore可以传入一个类型,来限制state中的成员
const store = createStore<IRootState>({
  state: () => {
    return {
      name: 'why',
      age: 23
    }
  },
  mutations: {},
  getters: {},
  actions: {},
  modules: {
    login
  }
})
export function setupStore() {
  store.dispatch('login/loadLocalLogin')
}
export function useStore(): Store<IStoreType> {
  return useVuexStore()
}
export default store

关于上述代码,

const store = createStore<IRootState>({ ... }): 这行代码创建了一个 Vuex store 实例,并且通过 来限制 state 的类型。在这个示例中,state 包含了一个名为 name 的属性(字符串类型)和一个名为 age 的属性(数字类型)。

store.dispatch('login/loadLocalLogin'): 在 setupStore 函数中,调用了 store 的 dispatch 方法,触发了一个名为 loadLocalLogin 的 action。这个 action 可能在 login 模块中定义,用于从本地存储中加载登录状态。

export function useStore(): Store<IStoreType> { ... }: 这个函数是一个自定义的 hook,用于获取 Vuex store 实例。它返回了通过 useVuexStore() 获取的 store 实例,并且限制了 store 的类型为 IStoreType。

export default store: 最后,将创建好的 Vuex store 实例导出,以便在 Vue 应用的其他部分使用。

比如在一个组件中,需要请求用户菜单信息,可以看到此时的store就有了具体类型,而不是文章开头的any类型。