157 lines
4.8 KiB
Plaintext
157 lines
4.8 KiB
Plaintext
import { defineStore } from 'pinia';
|
|
import { RouteLocationNormalized } from 'vue-router';
|
|
import { useAsyncRouteStore } from '@/store/modules/asyncRoute';
|
|
import { storage } from '@/utils/Storage';
|
|
import { TABS_ROUTES } from '@/store/mutation-types';
|
|
|
|
// 不需要出现在标签页中的路由
|
|
const whiteList = ['Redirect', 'Login'];
|
|
|
|
export type RouteItem = Partial<RouteLocationNormalized> & {
|
|
fullPath: string;
|
|
path: string;
|
|
name: string;
|
|
hash: string;
|
|
meta: object;
|
|
params: object;
|
|
query: object;
|
|
};
|
|
|
|
export type ITabsViewState = {
|
|
tabsList: RouteItem[]; // 标签页
|
|
};
|
|
|
|
//过滤当前路由
|
|
function filterCurrentRoute(list: any[], activeKey) {
|
|
return list.filter((item) => item.fullPath != activeKey);
|
|
}
|
|
|
|
//保留固定路由
|
|
function retainAffixRoute(list: any[]) {
|
|
return list.filter((item) => item?.meta?.affix ?? false);
|
|
}
|
|
|
|
//筛序最新的
|
|
function filterNewTabs(sliceTabs: any[], tabsList: any[], activeKey = '') {
|
|
const pathList: string[] = [];
|
|
for (const item of sliceTabs) {
|
|
const affix = item?.meta?.affix ?? false;
|
|
if (!affix) {
|
|
pathList.push(item.fullPath);
|
|
}
|
|
}
|
|
return tabsList.filter(
|
|
(item) => item.fullPath === activeKey || !pathList.includes(item.fullPath),
|
|
);
|
|
}
|
|
|
|
export const useTabsViewStore = defineStore({
|
|
id: 'app-tabs-view',
|
|
state: (): ITabsViewState => ({
|
|
tabsList: [],
|
|
}),
|
|
getters: {
|
|
getTabList(): RouteLocationNormalized[] {
|
|
return this.tabsList;
|
|
},
|
|
},
|
|
actions: {
|
|
//查找设置缓存name
|
|
findKeepAliveNames(list) {
|
|
const names = [];
|
|
list.forEach((item) => {
|
|
if (item.meta?.keepAlive) {
|
|
names.push(item.name);
|
|
}
|
|
});
|
|
return names;
|
|
},
|
|
//从缓存中删除关闭的路由
|
|
delKeepAliveNames(list) {
|
|
const asyncRouteStore = useAsyncRouteStore();
|
|
const names = this.findKeepAliveNames(list);
|
|
asyncRouteStore.removeKeepAliveComponents(names);
|
|
},
|
|
// 初始化标签页
|
|
initTabs(routes) {
|
|
this.tabsList = routes;
|
|
},
|
|
// 添加标签页
|
|
addTabs(route): boolean {
|
|
if (whiteList.includes(route.name)) return false;
|
|
const isExists = this.tabsList.some((item) => item.fullPath == route.fullPath);
|
|
if (!isExists) {
|
|
this.tabsList.push(route);
|
|
} else {
|
|
//如果是存在的路由,则刷新信息
|
|
const _index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
|
|
this.tabsList[_index] = route;
|
|
}
|
|
return true;
|
|
},
|
|
// 关闭左侧
|
|
closeLeftTabs(route, activeKey) {
|
|
const index = this.tabsList.findIndex((item) => item.fullPath == route.value.fullPath);
|
|
if (index > 0) {
|
|
const leftTabs = this.tabsList.slice(0, index);
|
|
const newLeftTabs = filterCurrentRoute(leftTabs, activeKey);
|
|
this.delKeepAliveNames(newLeftTabs);
|
|
this.tabsList = filterNewTabs(newLeftTabs, this.tabsList, activeKey);
|
|
}
|
|
},
|
|
// 关闭右侧
|
|
closeRightTabs(route, activeKey) {
|
|
const index = this.tabsList.findIndex((item) => item.fullPath == route.value.fullPath);
|
|
if (index >= 0 && index < this.tabsList.length - 1) {
|
|
const rightTabs = this.tabsList.slice(index + 1, this.tabsList.length);
|
|
const newRightTabs = filterCurrentRoute(rightTabs, activeKey);
|
|
this.delKeepAliveNames(newRightTabs);
|
|
this.tabsList = filterNewTabs(newRightTabs, this.tabsList, activeKey);
|
|
}
|
|
},
|
|
// 关闭其他
|
|
closeOtherTabs(route, activeKey) {
|
|
const newTabsList = this.tabsList.filter(
|
|
(item) =>
|
|
([route.value.fullPath, activeKey].includes(item.fullPath) || item?.meta?.affix) ?? false,
|
|
);
|
|
this.delKeepAliveNames(newTabsList);
|
|
this.tabsList = newTabsList;
|
|
},
|
|
// 关闭当前页
|
|
closeCurrentTab(route) {
|
|
const index = this.tabsList.findIndex((item) => item.fullPath == route.value.fullPath);
|
|
if (index != -1) {
|
|
this.delKeepAliveNames([this.tabsList[index]]);
|
|
this.tabsList.splice(index, 1);
|
|
}
|
|
},
|
|
// 关闭全部
|
|
closeAllTabs() {
|
|
this.delKeepAliveNames(this.tabsList);
|
|
this.tabsList = retainAffixRoute(this.tabsList);
|
|
},
|
|
// 设置标题
|
|
async setTabTitle(title: string, route: RouteLocationNormalized) {
|
|
this.tabsList.forEach((item) => {
|
|
if (item.fullPath === route.fullPath) {
|
|
item.meta.title = title;
|
|
}
|
|
});
|
|
storage.set(TABS_ROUTES, JSON.stringify(this.tabsList));
|
|
},
|
|
// 设置状态
|
|
async setTabState(params, route: RouteLocationNormalized) {
|
|
this.tabsList.forEach((item) => {
|
|
if (item.fullPath === route.fullPath) {
|
|
item.meta = {
|
|
...item.meta,
|
|
...params,
|
|
};
|
|
}
|
|
});
|
|
storage.set(TABS_ROUTES, JSON.stringify(this.tabsList));
|
|
},
|
|
},
|
|
});
|