Vben Admin 原始碼學習:狀態管理-專案配置
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__';
每個功能就如拼圖碎片,一開始講解起來有些有些割裂感,隨著系統程式碼不斷的深入解析, 整個拼圖會逐漸清晰,讓你從全域性掌握整體架構脈絡。