vuex@4与Typescript
简单分享一个使用Typescript给vuex的加上类型检测的技巧。只能对state有进行类型声明.
其他优秀解决方案,文末附跳转链接.
正文
简单搭建store结构
store/index.ts 根state
import { createStore } from 'vuex';
// 导入子模块
import home from './home/home';
import login from './login/login';
// 导入根模块类型
import type { IRootState } from './types';
// 在调用createStore是传入一个自己root的type
const store = createStore<IRootState>({
state: () => {
return {
name: 'red',
age: 20
};
},
getters: {},
mutations: {},
actions: {}
});
export default store;
store/home/home.ts 子模块home
import { Module } from 'vuex';
// 导入home的state类型
import type { IHomeState } from './home-types';
import type { IRootState } from '../types';
// 借助vuex中的 Module接口 给子模块传入本模块与父模块的state的类型.
// 第一个传本模块的类型,第二个传父模块的类型
const home: Module<IHomeState, IRootState> = {
namespaced: true,
state() {
return {
invitationProgress: 3
};
},
getters: {},
mutations: {},
actions: {}
};
export default home;
store/login.ts 子模块login
// 结构与home无异
import { Module } from 'vuex';
import type { ILoginState } from './login-types';
import type { IRootState } from '../types';
const login: Module<ILoginState, IRootState> = {
namespaced: true,
state() {
return {
login: 'hello we are login module'
};
},
getters: {},
mutations: {},
actions: {}
};
export default login;
主角 关键
store/types.ts
// 导入子模块home的类型
import { IHomeState } from './home/home-types';
import { ILoginState } from './login/login-types';
// root模块的类型
export interface IRootState {
name: string;
age: number;
}
// 写一个所有子模块类型的接口
export interface IModuleState {
home: IHomeState;
login: ILoginState;
}
// 将根模块与子模块接口合并导出
export type IStore = IRootState & IModuleState;
回到store/index.ts
// 1.在这里导入useStore,为了区别自己导出的useStore给他取一个别名为useVuexStore(随意)
import { createStore, Store, useStore as useVuexStore } from 'vuex';
import home from './home/home';
import login from './login/login';
import type { IRootState } from './types';
// 2.导入整个store的类型
import type { IStore } from './types';
const store = createStore<IRootState>({
...
})
export default store;
// 2.自己写一个useStore并导出. 函数返回值是Store,Store的类型的是自己编写的IStore.
export function useStore(): Store<IStore> {
// 执行从vuex导入useStore并return出去
return useVuexStore();
}
简单测试
// 从此不再使用vuex里面的useStore
// import { useStore } from 'vuex';
// 从自己的store/index.ts 导出store使用
import { useStore } from '@/store';
const store = useStore();
console.log(store.state.name);
成功提示
来自coderwhy
==
其他方案链接
vuex@4官方文档的方式
TypeScript 支持 | Vuex (vuejs.org)
使用Pinia
- vue核心团队成员 posva (Eduardo San Martin Morote) 开发
- 与vuex的API几乎一样, 易上手.
- 支持 Vue.js devtools , 为您提供增强的Vue2和Vue3开发体验。
- 无需像 Vuex@4自定义复杂的类型来支持 typescript,天生具备完美的类型推断。
- Pinia 大小约1kb