Vben Admin 源码学习:状态管理-项目配置
2022-05-30 21:47 Anduril 阅读(1940) 评论(0) 编辑 收藏 举报0x00 前言
本文将对 Vue-Vben-Admin 的状态管理实现源码进行分析解读,耐心读完,相信您一定会有所收获!
0x01 数据仓库
项目状态管理代码实现在 src/store/
目录下, 使用新一代的状态管理器 Pinia
, 具体特性详见 官网 。
文件 src/store/index.ts
中调用 createPinia()
创建一个pinia 实例,声明方法 setupStore()
并导出,在主入口文件中调用此方法即可将 pinia 实例注册到应用程序中。
同时单独将 pinia 实例导出,用于在 setup()
函数外使用 pinia store 实例。
import { createPinia } from 'pinia';
// 创建一个 pinia(根存储)
const store = createPinia();
// 注册到应用程序
export function setupStore(app: App<Element>) {
app.use(store);
}
// 单独将pinia 实例导出
export { store };
在 src/store/modules
目录下,各个文件中定义不同的 store 实例,主要用于项目配置、错误日志、国际化、锁屏、多标签、菜单路由权限、用户状态等状态管理。
├── store # 数据仓库
│ ├── index.ts
│ ├── modules
│ │ ├── app.ts # 项目配置
│ │ ├── errorLog.ts # 错误日志
│ │ ├── locale.ts # 国际化/多语言
│ │ ├── lock.ts # 系统锁屏
│ │ ├── multipleTab.ts # 多标签
│ │ ├── permission.ts # 权限/菜单/路由
│ │ └── user.ts # 用户状态
接下来将对每个文件一一讲解。
0x02 app.ts 项目配置
文件 src\store\modules\app.ts
声明导出一个store实例 useAppStore
、一个方法 useAppStoreWithOut()
用于没有使用 setup
组件时使用。
// 项目配置存储实例
export const useAppStore = defineStore({
id: 'app', // 也称为 name,是必要的,Pinia 使用它来将 store 连接到 devtools。
state: {},
getters: {}
actions:{}
});
export function useAppStoreWithOut() {
return useAppStore(store);
}
state
状态对象定义了主题模式、页面加载状态、项目配置、菜单状态快照等。
state: (): AppState => ({
darkMode: undefined, // 主题模式 dark|light
pageLoading: false, // 页面加载状态
projectConfig: Persistent.getLocal(PROJ_CFG_KEY), // 项目配置 ProjectConfig
beforeMiniInfo: {}, // BeforeMiniState
}),
projectConfig
属性用于配置项目内展示的内容、布局、文本等效果,具体配置文件路径 src/settings/projectSetting.ts
, 属性定义由于篇幅原因请直接查看官网的 项目配置说明 。
projectConfig
的初始化值从缓存中获取,而不是从文件中引入,这个后面会有单独篇幅进行讲解。
beforeMiniInfo
属性用于当窗口缩小时记住菜单状态,并在恢复窗口时恢复这些状态(是否折叠、是否分割、类型、模式)。
export interface BeforeMiniState {
menuCollapsed?: boolean; // 菜单折叠
menuSplit?: boolean; // 分割菜单
menuMode?: MenuModeEnum; // 菜单类型
menuType?: MenuTypeEnum; // 菜单模式
}
Getter
Getter
等同于 Store 状态的计算值(计算属性)。
getters: {
// 页面加载状态
getPageLoading(): boolean {
return this.pageLoading;
},
// 主题模式
getDarkMode(): 'light' | 'dark' | string {
return this.darkMode || localStorage.getItem(APP_DARK_MODE_KEY_) || darkMode;
},
// 菜单状态快照
getBeforeMiniInfo(): BeforeMiniState {
return this.beforeMiniInfo;
},
// 项目配置
getProjectConfig(): ProjectConfig {
return this.projectConfig || ({} as ProjectConfig);
},
// 头部配置
getHeaderSetting(): HeaderSetting {
return this.getProjectConfig.headerSetting;
},
// 菜单配置
getMenuSetting(): MenuSetting {
return this.getProjectConfig.menuSetting;
},
// 动画配置
getTransitionSetting(): TransitionSetting {
return this.getProjectConfig.transitionSetting;
},
// 多标签配置
getMultiTabsSetting(): MultiTabsSetting {}
return this.getProjectConfig.multiTabsSetting;
},
},
其中 getDarkMode()
根据 state.darkMode
、localStorage 存储和 配置文件的定义值darkMode 进行计算。
// src\settings\designSetting.ts
export const darkMode = ThemeEnum.LIGHT;
Actions
Actions
相当于组件中的 methods,主要用于设置state对象。
actions: {
// 设置页面加载状态
setPageLoading(loading: boolean): void {
this.pageLoading = loading;
},
// 设置主题模式 存于`localStorage`中
setDarkMode(mode: ThemeEnum): void {
this.darkMode = mode;
localStorage.setItem(APP_DARK_MODE_KEY_, mode);
},
// 设置页面加载状态
setBeforeMiniInfo(state: BeforeMiniState): void {
this.beforeMiniInfo = state;
},
// 设置项目配置 项目自带的缓存类进行缓存操作
setProjectConfig(config: DeepPartial<ProjectConfig>): void {
this.projectConfig = deepMerge(this.projectConfig || {}, config);
Persistent.setLocal(PROJ_CFG_KEY, this.projectConfig);
},
// 重置路由
async resetAllState() {
resetRouter();
Persistent.clearAll(); // 清空缓存
},
// 使用定时器设置页面加载状态
async setPageLoadingAction(loading: boolean): Promise<void> {
if (loading) {
clearTimeout(timeId);
// Prevent flicker 防止闪烁
timeId = setTimeout(() => {
this.setPageLoading(loading);
}, 50);
} else {
this.setPageLoading(loading);
clearTimeout(timeId);
}
},
},
其他
在缓存、localStorage操作中使用了存储KEY,它定义在 src\enums\cacheEnum.ts
文件中。
import { APP_DARK_MODE_KEY_, PROJ_CFG_KEY } from '/@/enums/cacheEnum';
// src\enums\cacheEnum.ts
export const APP_DARK_MODE_KEY_ = '__APP__DARK__MODE__';
export const APP_LOCAL_CACHE_KEY = 'COMMON__LOCAL__KEY__';
每个功能就如拼图碎片,一开始讲解起来有些有些割裂感,随着系统代码不断的深入解析, 整个拼图会逐渐清晰,让你从全局掌握整体架构脉络。
作者:Anduril
掘金传送门:掘金/Andurils
技术只有不沉浸其中才能对其更加公正看待! 没了狂热和浮躁,去体会下开源下的语法魅力!这里没有技术宗教的狂热和鄙夷,没有疯狂的个人崇拜,只是一个技术人探索之路上对于美丽与丑陋的随笔和感悟!
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。