diff --git a/src/plugins/element-plus/index.ts b/src/plugins/element-plus/index.ts index 380943f44..7218d3eb2 100644 --- a/src/plugins/element-plus/index.ts +++ b/src/plugins/element-plus/index.ts @@ -41,6 +41,8 @@ import { ElTabPane, ElAvatar, ElEmpty, + ElCollapse, + ElCollapseItem, // 指令 ElLoading, ElInfiniteScroll @@ -106,7 +108,9 @@ const components = [ ElTabs, ElTabPane, ElAvatar, - ElEmpty + ElEmpty, + ElCollapse, + ElCollapseItem ]; // icon export const iconComponents = [ diff --git a/src/router/index.ts b/src/router/index.ts index 45dc387d6..f70f386c5 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -137,7 +137,7 @@ export const addAsyncRoutes = (arrRoutes: Array) => { // 创建路由实例 export const router: Router = createRouter({ history: createWebHashHistory(), - routes: filterTree(ascending(constantRoutes)).concat(...remainingRouter), + routes: ascending(constantRoutes).concat(...remainingRouter), scrollBehavior(to, from, savedPosition) { return new Promise(resolve => { if (savedPosition) { diff --git a/src/router/modules/tabs.ts b/src/router/modules/tabs.ts index 60986eed1..9d9378699 100644 --- a/src/router/modules/tabs.ts +++ b/src/router/modules/tabs.ts @@ -22,6 +22,18 @@ const tabsRouter = { showLink: true, i18n: true } + }, + { + path: "/tabs/detail/:id", + name: "tabDetail", + component: () => import("/@/views/tabs/tabDetail.vue"), + meta: { + title: "", + showLink: false, + i18n: false, + dynamicLevel: 3, + realPath: "/tabs/detail" + } } ] }; diff --git a/src/store/modules/multiTags.ts b/src/store/modules/multiTags.ts index c6ee7d5e6..a78d5eabf 100644 --- a/src/store/modules/multiTags.ts +++ b/src/store/modules/multiTags.ts @@ -4,6 +4,13 @@ import { getConfig } from "/@/config"; import { positionType } from "./types"; import { storageLocal } from "/@/utils/storage"; +interface Itag { + path: string; + parentPath: string; + name: string; + meta: any; +} + export const useMultiTagsStore = defineStore({ id: "pure-multiTags", state: () => ({ @@ -34,14 +41,44 @@ export const useMultiTagsStore = defineStore({ this.getMultiTagsCache && storageLocal.setItem("responsive-tags", multiTags); }, - handleTags(mode: string, value?: T, position?: positionType): any { + handleTags( + mode: string, + value?: T | Itag, + position?: positionType + ): any { switch (mode) { case "equal": this.multiTags = value; break; case "push": - this.multiTags.push(value); - this.tagsCache(this.multiTags); + { + const tagVal = value as Itag; + // 判断tag是否已存在: + const tagHasExits = this.multiTags.some(tag => { + return tag.path === tagVal?.path; + }); + + if (tagHasExits) return; + const meta = tagVal?.meta; + const dynamicLevel = meta?.dynamicLevel ?? -1; + if (dynamicLevel > 0) { + // dynamicLevel动态路由可打开的数量 + const realPath = meta?.realPath ?? ""; + // 获取到已经打开的动态路由数, 判断是否大于dynamicLevel + if ( + this.multiTags.filter(e => e.meta?.realPath ?? "" === realPath) + .length >= dynamicLevel + ) { + // 关闭第一个 + const index = this.multiTags.findIndex( + item => item.meta?.realPath === realPath + ); + index !== -1 && this.multiTags.splice(index, 1); + } + } + this.multiTags.push(value); + this.tagsCache(this.multiTags); + } break; case "splice": this.multiTags.splice(position?.startIndex, position?.length); diff --git a/src/views/tabs/index.vue b/src/views/tabs/index.vue index 25c492cfe..af57aac0f 100644 --- a/src/views/tabs/index.vue +++ b/src/views/tabs/index.vue @@ -1,10 +1,50 @@ - + diff --git a/src/views/tabs/tabDetail.vue b/src/views/tabs/tabDetail.vue new file mode 100644 index 000000000..79abc9c0f --- /dev/null +++ b/src/views/tabs/tabDetail.vue @@ -0,0 +1,11 @@ + + + + +