上述代码中,想要从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类型。