天天看點

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: {
  // 設定頁面加載狀态
  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);
    }
  },
},      

其他

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__';      

繼續閱讀