Vben Admin 多標(biāo)簽頁(yè)狀態(tài)管理源碼學(xué)習(xí)
引言
本文將對(duì) Vue-Vben-Admin 的狀態(tài)管理實(shí)現(xiàn)源碼進(jìn)行分析解讀,耐心讀完,相信您一定會(huì)有所收獲!
multipleTab.ts 系統(tǒng)鎖屏
文件 src\store\modules\multipleTab.ts 聲明導(dǎo)出一個(gè)store實(shí)例 useMultipleTabStore 、一個(gè)方法 useMultipleTabWithOutStore()用于沒有使用 setup 組件時(shí)使用。
// 多標(biāo)簽頁(yè)信息存儲(chǔ)
export const useMultipleTabStore = defineStore({
id: 'app-multiple-tab',
state: { /*...*/ },
getters: { /*...*/ }
actions:{ /*...*/ }
});
export function useMultipleTabWithOutStore() {
return useMultipleTabStore(store);
}
State/Getter
狀態(tài)對(duì)象定義了標(biāo)簽頁(yè)路由列表、緩存標(biāo)簽頁(yè)名稱以及最后一次拖動(dòng)標(biāo)簽的索引。同時(shí)提供了對(duì)應(yīng)方法用于獲取該狀態(tài)值。
// 多標(biāo)簽頁(yè)狀態(tài)
export interface MultipleTabState {
cacheTabList: Set<string>; // 緩存標(biāo)簽頁(yè)路由名稱
// 標(biāo)簽頁(yè)路由列表 RouteLocationNormalized 路由記錄的標(biāo)準(zhǔn)化版本
tabList: RouteLocationNormalized[];
lastDragEndIndex: number; // 最后一次拖動(dòng)標(biāo)簽的索引
}
state: (): MultipleTabState => ({
cacheTabList: new Set(),
tabList: cacheTab ? Persistent.getLocal(MULTIPLE_TABS_KEY) || [] : [], // 優(yōu)先加載緩存/本地存儲(chǔ)內(nèi)容
lastDragEndIndex: 0,
}),
getters: {
// 獲取標(biāo)簽頁(yè)路由列表
getTabList(): RouteLocationNormalized[] {
return this.tabList;
},
// 獲取緩存標(biāo)簽頁(yè)路由名稱列表
getCachedTabList(): string[] {
return Array.from(this.cacheTabList);
},
// 獲取最后一次拖動(dòng)標(biāo)簽的索引
getLastDragEndIndex(): number {
return this.lastDragEndIndex;
},
},
Actions
方法 addTab 方法用于打開標(biāo)簽頁(yè)。
- 判斷當(dāng)前打開是否特殊頁(yè)面(錯(cuò)誤處理/登錄/重定向)。
- 若存在已經(jīng)打開路徑相同的標(biāo)tianj簽頁(yè),更新其標(biāo)簽頁(yè)路由記錄,否則添加新頁(yè)面路由記錄。
- 更新需要緩存的標(biāo)簽頁(yè)路由名稱,使用本地存儲(chǔ)持久化。
// 打開標(biāo)簽頁(yè)
async addTab(route: RouteLocationNormalized) {
// 路由基本屬性
const { path, name, fullPath, params, query, meta } = getRawRoute(route);
// 錯(cuò)誤處理頁(yè)面 登錄 重定向 等頁(yè)面
if (
path === PageEnum.ERROR_PAGE ||
path === PageEnum.BASE_LOGIN ||
!name ||
[REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string)
) {
return;
}
let updateIndex = -1;
// 標(biāo)簽頁(yè)已經(jīng)存在,不在重復(fù)添加標(biāo)簽
const tabHasExits = this.tabList.some((tab, index) => {
updateIndex = index;
return (tab.fullPath || tab.path) === (fullPath || path);
});
// 標(biāo)簽已經(jīng)存在,執(zhí)行更新操作
if (tabHasExits) {
const curTab = toRaw(this.tabList)[updateIndex]; // 獲取當(dāng)前標(biāo)簽頁(yè)路由記錄
if (!curTab) {
return;
}
curTab.params = params || curTab.params; // 從 path 中提取的已解碼參數(shù)字典
curTab.query = query || curTab.query; // 從 URL 的 search 部分提取的已解碼查詢參數(shù)的字典。
curTab.fullPath = fullPath || curTab.fullPath; // URL 編碼與路由地址有關(guān)。包括 path、 query 和 hash。
this.tabList.splice(updateIndex, 1, curTab); // 替換原有的標(biāo)簽頁(yè)路由記錄
} else {
// 添加標(biāo)簽頁(yè)
// 獲取動(dòng)態(tài)路由打開數(shù),超過 0 即代表需要控制打開數(shù)
const dynamicLevel = meta?.dynamicLevel ?? -1;
if (dynamicLevel > 0) {
// 如果設(shè)置大于 0 了,那么就要限制該路由的打開數(shù)限制了
// 首先獲取到真實(shí)的路由,使用配置方式減少計(jì)算開銷.
// const realName: string = path.match(/(\S*)\//)![1];
const realPath = meta?.realPath ?? '';
// 獲取到已經(jīng)打開的動(dòng)態(tài)路由數(shù), 判斷是否大于某一個(gè)值
if (
this.tabList.filter((e) => e.meta?.realPath ?? '' === realPath).length >= dynamicLevel
) {
// 關(guān)閉第一個(gè)
const index = this.tabList.findIndex((item) => item.meta.realPath === realPath);
index !== -1 && this.tabList.splice(index, 1);
}
}
this.tabList.push(route); // 添加至路由列表中
}
this.updateCacheTab();
// 使用本地存儲(chǔ)持久化
cacheTab && Persistent.setLocal(MULTIPLE_TABS_KEY, this.tabList);
},
方法updateCacheTab用于更新需要緩存的標(biāo)簽頁(yè)路由名稱,返回一個(gè) Set 集合。若路由中meta中設(shè)置ignoreKeepAlive為 true,該標(biāo)簽頁(yè)不會(huì)被緩存。
// 根據(jù)當(dāng)前打開的標(biāo)簽更新緩存
async updateCacheTab() {
// Set 集合存儲(chǔ)
const cacheMap: Set<string> = new Set();
for (const tab of this.tabList) {
const item = getRawRoute(tab);
// 若忽略KeepAlive緩存 不緩存
const needCache = !item.meta?.ignoreKeepAlive;
if (!needCache) {
continue;
}
const name = item.name as string;
cacheMap.add(name);
}
this.cacheTabList = cacheMap; // 存儲(chǔ)路由記錄名稱的 Set 集合
},
方法setTabTitle使用meta屬性,將最新標(biāo)題內(nèi)容附加到路由上。
// 設(shè)置標(biāo)簽標(biāo)題
async setTabTitle(title: string, route: RouteLocationNormalized) {
const findTab = this.getTabList.find((item) => item === route);
if (findTab) {
findTab.meta.title = title; // meta實(shí)現(xiàn) 設(shè)置每個(gè)頁(yè)面的title標(biāo)題
await this.updateCacheTab();
}
},
在標(biāo)簽頁(yè)組件中,根據(jù)傳入打開頁(yè)面路由記錄tabItem,標(biāo)簽頁(yè)標(biāo)題名稱綁定計(jì)算屬性 getTitle 。
// src\layouts\default\tabs\components\TabContent.vue
<template>
<Dropdown :dropMenuList="getDropMenuList" :trigger="getTrigger" @menu-event="handleMenuEvent">
<div :class="`${prefixCls}__info`" @contextmenu="handleContext" v-if="getIsTabs">
<span class="ml-1">{{ getTitle }}</span>
</div>
</Dropdown>
</template>
props: {
tabItem: {
type: Object as PropType<RouteLocationNormalized>,
default: null,
},
isExtra: Boolean,
},
// 獲取標(biāo)題信息
const getTitle = computed(() => {
const { tabItem: { meta } = {} } = props;
return meta && t(meta.title as string);
});以上就是Vben Admin 多標(biāo)簽頁(yè)狀態(tài)管理源碼學(xué)習(xí)的詳細(xì)內(nèi)容,更多關(guān)于Vben Admin 多標(biāo)簽頁(yè)狀態(tài)管理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
iview給radio按鈕組件加點(diǎn)擊事件的實(shí)例
下面小編就為大家?guī)硪黄猧view給radio按鈕組件加點(diǎn)擊事件的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
Vue結(jié)合ElementUI實(shí)現(xiàn)數(shù)據(jù)請(qǐng)求和頁(yè)面跳轉(zhuǎn)功能(最新推薦)
我們?cè)赑roflie.vue實(shí)例中,有beforeRouteEnter、beforeRouteLeave兩個(gè)函數(shù)分別是進(jìn)入路由之前和離開路由之后,我們可以在這兩個(gè)函數(shù)之內(nèi)進(jìn)行數(shù)據(jù)的請(qǐng)求,下面給大家分享Vue結(jié)合ElementUI實(shí)現(xiàn)數(shù)據(jù)請(qǐng)求和頁(yè)面跳轉(zhuǎn)功能,感興趣的朋友一起看看吧2024-05-05
Vue中實(shí)現(xiàn)滾動(dòng)加載與無限滾動(dòng)
本文主要介紹了Vue中實(shí)現(xiàn)滾動(dòng)加載與無限滾動(dòng),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
在vue中實(shí)現(xiàn)PDF文件流預(yù)覽功能
這篇文章主要為大家詳細(xì)介紹如何在vue中實(shí)現(xiàn)PDF文件流預(yù)覽功能,文中的實(shí)現(xiàn)步驟講解詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考價(jià)值,需要的可以參考一下2023-12-12
vue如何在項(xiàng)目中調(diào)用騰訊云的滑動(dòng)驗(yàn)證碼
這篇文章主要介紹了vue如何在項(xiàng)目中調(diào)用騰訊云的滑動(dòng)驗(yàn)證碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
vue?懶加載組件chunk相對(duì)路徑混亂問題及解決
這篇文章主要介紹了vue?懶加載組件chunk相對(duì)路徑混亂問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04

