vue-vben-admin/src/store/modules/tab.ts

258 lines
7.5 KiB
TypeScript
Raw Normal View History

2020-09-28 20:19:10 +08:00
import { computed, toRaw } from 'vue';
import type { AppRouteRecordRaw, RouteMeta } from '/@/router/types.d';
import { unref } from 'vue';
import { Action, Module, Mutation, VuexModule, getModule } from 'vuex-module-decorators';
import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
import { PageEnum } from '/@/enums/pageEnum';
import { appStore } from '/@/store/modules/app';
2020-11-10 21:58:19 +08:00
import { userStore } from './user';
2020-09-28 20:19:10 +08:00
import store from '/@/store';
import router from '/@/router';
import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/constant';
2020-10-14 21:08:07 +08:00
import { getCurrentTo } from '/@/utils/helper/routeHelper';
2020-09-28 20:19:10 +08:00
type CacheName = string | symbol | null | undefined;
2020-11-21 22:47:10 +08:00
2020-09-28 20:19:10 +08:00
/**
* @description: vuex Tab模块
*/
// declare namespace TabsStore {
export interface TabItem {
2020-10-14 21:08:07 +08:00
fullPath: string;
path?: string;
params?: any;
query?: any;
2020-09-28 20:19:10 +08:00
name?: CacheName;
meta?: RouteMeta;
}
const NAME = 'tab';
2020-11-21 22:47:10 +08:00
2020-09-28 20:19:10 +08:00
hotModuleUnregisterModule(NAME);
const getOpenKeepAliveRef = computed(() => appStore.getProjectConfig.openKeepAlive);
@Module({ namespaced: true, name: NAME, dynamic: true, store })
class Tab extends VuexModule {
2020-10-30 21:32:05 +08:00
// tab list
2020-09-28 20:19:10 +08:00
tabsState: TabItem[] = [];
2020-10-30 21:32:05 +08:00
// tab cache list
2020-09-28 20:19:10 +08:00
keepAliveTabsState: CacheName[] = [];
currentContextMenuIndexState = -1;
currentContextMenuState: TabItem | null = null;
2020-11-10 21:58:19 +08:00
// Last route change
lastChangeRouteState: AppRouteRecordRaw | null = null;
2020-09-28 20:19:10 +08:00
get getTabsState() {
return this.tabsState;
}
2020-11-10 21:58:19 +08:00
get getLastChangeRouteState() {
return this.lastChangeRouteState;
}
2020-09-28 20:19:10 +08:00
get getCurrentContextMenuIndexState() {
return this.currentContextMenuIndexState;
}
get getCurrentContextMenuState() {
return this.currentContextMenuState;
}
get getKeepAliveTabsState() {
return this.keepAliveTabsState;
}
get getCurrentTab(): TabItem {
const route = unref(router.currentRoute);
return this.tabsState.find((item) => item.path === route.path)!;
}
2020-11-10 21:58:19 +08:00
@Mutation
commitLastChangeRouteState(route: AppRouteRecordRaw): void {
if (!userStore.getTokenState) return;
this.lastChangeRouteState = route;
}
2020-09-28 20:19:10 +08:00
@Mutation
commitClearCache(): void {
this.keepAliveTabsState = [];
}
@Mutation
commitCurrentContextMenuIndexState(index: number): void {
this.currentContextMenuIndexState = index;
}
@Mutation
commitCurrentContextMenuState(item: TabItem): void {
this.currentContextMenuState = item;
}
/**
* @description: add tab
*/
@Mutation
commitAddTab(route: AppRouteRecordRaw | TabItem): void {
2020-10-14 21:08:07 +08:00
const { path, name, meta, fullPath, params, query } = route as TabItem;
2020-09-28 20:19:10 +08:00
// 404 页面不需要添加tab
2020-11-10 21:58:19 +08:00
if (path === PageEnum.ERROR_PAGE || !name) {
2020-09-28 20:19:10 +08:00
return;
} else if ([REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string)) {
return;
}
2020-10-14 21:08:07 +08:00
let updateIndex = -1;
2020-09-28 20:19:10 +08:00
// 已经存在的页面不重复添加tab
const hasTab = this.tabsState.some((tab, index) => {
updateIndex = index;
return (tab.fullPath || tab.path) === (fullPath || path);
2020-09-28 20:19:10 +08:00
});
if (hasTab) {
const curTab = toRaw(this.tabsState)[updateIndex];
if (!curTab) return;
curTab.params = params || curTab.params;
curTab.query = query || curTab.query;
curTab.fullPath = fullPath || curTab.fullPath;
this.tabsState.splice(updateIndex, 1, curTab);
return;
}
2020-10-14 21:08:07 +08:00
this.tabsState.push({ path, fullPath, name, meta, params, query });
2020-09-28 20:19:10 +08:00
if (unref(getOpenKeepAliveRef) && name) {
const noKeepAlive = meta && meta.ignoreKeepAlive;
const hasName = this.keepAliveTabsState.includes(name);
!noKeepAlive && !hasName && this.keepAliveTabsState.push(name);
}
}
/**
* @description: close tab
*/
@Mutation
commitCloseTab(route: AppRouteRecordRaw | TabItem): void {
try {
2020-10-14 21:08:07 +08:00
const { fullPath, name, meta: { affix } = {} } = route;
2020-09-28 20:19:10 +08:00
if (affix) return;
2020-10-14 21:08:07 +08:00
const index = this.tabsState.findIndex((item) => item.fullPath === fullPath);
2020-09-28 20:19:10 +08:00
index !== -1 && this.tabsState.splice(index, 1);
if (unref(getOpenKeepAliveRef) && name) {
const i = this.keepAliveTabsState.findIndex((item) => item === name);
i !== -1 && this.keepAliveTabsState.splice(i, 1);
}
} catch (error) {}
}
@Mutation
commitCloseTabKeepAlive(route: AppRouteRecordRaw | TabItem): void {
const { name } = route;
if (unref(getOpenKeepAliveRef) && name) {
const i = this.keepAliveTabsState.findIndex((item) => item === name);
i !== -1 && toRaw(this.keepAliveTabsState).splice(i, 1);
}
}
@Mutation
commitCloseAllTab(): void {
this.tabsState = this.tabsState.filter((item) => {
return item.meta && item.meta.affix;
});
const names = this.tabsState.map((item) => item.name);
this.keepAliveTabsState = names as string[];
}
@Mutation
commitResetState(): void {
this.tabsState = [];
this.currentContextMenuState = null;
this.currentContextMenuIndexState = -1;
this.keepAliveTabsState = [];
}
@Mutation
closeMultipleTab({ pathList, nameList }: { pathList: string[]; nameList: string[] }): void {
2020-10-14 21:08:07 +08:00
this.tabsState = toRaw(this.tabsState).filter((item) => !pathList.includes(item.fullPath));
2020-09-28 20:19:10 +08:00
if (unref(getOpenKeepAliveRef) && nameList) {
this.keepAliveTabsState = toRaw(this.keepAliveTabsState).filter(
(item) => !nameList.includes(item as string)
);
}
}
@Action
closeLeftTabAction(route: AppRouteRecordRaw | TabItem): void {
const index = this.tabsState.findIndex((item) => item.path === route.path);
if (index > 0) {
const leftTabs = this.tabsState.slice(0, index);
const pathList: string[] = [];
const nameList: string[] = [];
for (const item of leftTabs) {
const affix = item.meta ? item.meta.affix : false;
if (!affix) {
2020-10-14 21:08:07 +08:00
pathList.push(item.fullPath);
2020-09-28 20:19:10 +08:00
nameList.push(item.name as string);
}
}
this.closeMultipleTab({ pathList, nameList });
}
}
@Action
2020-10-14 21:08:07 +08:00
addTabByPathAction(): void {
const toRoute = getCurrentTo();
if (!toRoute) return;
const { meta } = toRoute;
if (meta && meta.affix) {
return;
}
this.commitAddTab((toRoute as unknown) as AppRouteRecordRaw);
}
2020-09-28 20:19:10 +08:00
@Action
closeRightTabAction(route: AppRouteRecordRaw | TabItem): void {
2020-10-14 21:08:07 +08:00
const index = this.tabsState.findIndex((item) => item.fullPath === route.fullPath);
2020-09-28 20:19:10 +08:00
if (index >= 0 && index < this.tabsState.length - 1) {
const rightTabs = this.tabsState.slice(index + 1, this.tabsState.length);
const pathList: string[] = [];
const nameList: string[] = [];
for (const item of rightTabs) {
const affix = item.meta ? item.meta.affix : false;
if (!affix) {
2020-10-14 21:08:07 +08:00
pathList.push(item.fullPath);
2020-09-28 20:19:10 +08:00
nameList.push(item.name as string);
}
}
this.closeMultipleTab({ pathList, nameList });
}
}
@Action
closeOtherTabAction(route: AppRouteRecordRaw | TabItem): void {
2020-10-14 21:08:07 +08:00
const closePathList = this.tabsState.map((item) => item.fullPath);
2020-09-28 20:19:10 +08:00
const pathList: string[] = [];
const nameList: string[] = [];
closePathList.forEach((path) => {
2020-10-14 21:08:07 +08:00
if (path !== route.fullPath) {
2020-09-28 20:19:10 +08:00
const closeItem = this.tabsState.find((item) => item.path === path);
if (!closeItem) return;
const affix = closeItem.meta ? closeItem.meta.affix : false;
if (!affix) {
2020-10-14 21:08:07 +08:00
pathList.push(closeItem.fullPath);
2020-09-28 20:19:10 +08:00
nameList.push(closeItem.name as string);
}
}
});
this.closeMultipleTab({ pathList, nameList });
}
}
export const tabStore = getModule<Tab>(Tab);