老婆镇楼!
最近使用pinia作为新项目的状态管理,无论是定义还是使用都很简单易用,也结合ts和pinia选项式 (setup的也很喜欢,很自由,但个人觉得选项式更适合团队理解,简单明了) 整理了一套store的套路结构。
目录结构
.
|-- data # data store
| |-- actions-types.ts # action接口定义
| |-- actions.ts # action定义
| |-- getters.ts # getters定义
| |-- state.ts # state定义
| `-- index.ts # 导出文件
|-- index.ts # 导出文件
|-- type.ts # store泛型工具
type.ts
这里只放了一个结合defineStore actions options
和 自定义的state
、actions
接口,创建给actions.ts
使用的泛型工具。方便actions.ts
的ts提示。
import { PiniaCustomProperties, StateTree, _GettersTree, _StoreWithGetters, _StoreWithState } from 'pinia';
import { UnwrapRef } from 'vue';
export type CreateActions<Id extends string, S extends StateTree, A> = A &
ThisType<A & UnwrapRef<S> & _StoreWithState<Id, S, _GettersTree<S>, A> & _StoreWithGetters<_GettersTree<S>> & PiniaCustomProperties>;
export type CreateGetters<S extends StateTree, G extends _GettersTree<S>> = G &
ThisType<UnwrapRef<S> & _StoreWithGetters<G> & PiniaCustomProperties> &
_GettersTree<S>;
index.ts
这是store的主要输出文件,导出的registerStore
负责在main.ts
初始化。
import { useStore as dataStore, DataStore } from './data';
export interface IAppStore {
data: ReturnType<DataStore>;
}
const store: IAppStore = {} as IAppStore;
/**
* 注册app状态库
*/
export const registerStore = () => {
store.data = dataStore();
};
export default store;
main.ts
import { createApp, Component } from 'vue';
import { createPinia } from 'pinia';
import { registerStore } from '@/store';
import App from './App.vue';
const app = createApp(App);
app.use(createPinia());
// 注册pinia状态管理库
registerStore();
app.mount('#app');
state.ts
state定义
export interface DataState {
users:Map<string, { [key: string]: SafeAny }>
}
export const state: DataState = {
users: []
};
getters.ts
getters定义
import { _GettersTree } from 'pinia';
import { CreateGetters } from '../type';
import { DataState } from './state';
export type Getters = {
/** 有未读信息的 */
hadUnread(): boolean;
};
export type DataGetters = CreateGetters<DataState, Getters>;
export const getters: DataGetters = {
hadUnread() {
return this.notify.system.unreadNum > 0;
}
};
actions-types.ts
使用CreateActions创建的类型,可以完美得到的this方法和state的提示
import { SafeAny } from '@/app/shared/types/yacommon';
import { CreateActions } from '../type';
import { DataState } from './state';
interface Action {
queryUsers(): void;
}
export type DateActions = CreateActions<string, DataState, Action>;
actions.ts
import { DateActions } from './actions-types';
export const actions: DateActions = {
queryUsers() {
...
}
};
data/index.ts
选项式组合defineStore
import { defineStore, StoreDefinition, acceptHMRUpdate } from 'pinia';
import { state, DataState } from './state';
import { actions } from './actions';
import { DateActions } from './actions-types';
import { getters, DataGetters } from './getters';
export type DataStore = StoreDefinition<string, DataState, DataGetters, DateActions>;
export const useStore: DataStore = defineStore('data', {
state: () => state,
actions,
getters
});
if (import.meta.hot) import.meta.hot.accept(acceptHMRUpdate(useStore, import.meta.hot));
关于 acceptHMRUpdate
开发过程中发现,发现vite在热更新时,有store丢失的情况,在pinia的issues找到了相同的问题 ->传送门
- pinia: v2.0.14
- vite: v2.9.12
if (import.meta.hot) import.meta.hot.accept(acceptHMRUpdate(useStore, import.meta.hot));
结语
这样一套下来,开发体验理解简答,已维护。 使用只需要。
import store from '@/store';
store.data.queryUsers();
console.log(store.data.users);
欢迎大家实践!