diff --git a/src/layout/components/tag/index.scss b/src/layout/components/tag/index.scss index 97ae3b2e1..2079816a9 100644 --- a/src/layout/components/tag/index.scss +++ b/src/layout/components/tag/index.scss @@ -142,7 +142,7 @@ transition: transform 0.5s ease-in-out; .scroll-item { - transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); + transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); &:nth-child(1) { margin-left: 5px; diff --git a/src/layout/components/tag/index.vue b/src/layout/components/tag/index.vue index 4dcd67614..452edbfa6 100644 --- a/src/layout/components/tag/index.vue +++ b/src/layout/components/tag/index.vue @@ -17,6 +17,7 @@ import closeLeft from "/@/assets/svg/close_left.svg"; import closeOther from "/@/assets/svg/close_other.svg"; import closeRight from "/@/assets/svg/close_right.svg"; +import { isEqual } from "lodash-es"; import { emitter } from "/@/utils/mitt"; import { transformI18n } from "/@/plugins/i18n"; import { storageLocal } from "/@/utils/storage"; @@ -46,6 +47,61 @@ let multiTags: ComputedRef> = computed(() => { return useMultiTagsStoreHook()?.multiTags; }); +const linkIsActive = computed(() => { + return item => { + if (Object.keys(route.query).length === 0) { + if (route.path === item.path) { + return "is-active"; + } else { + return ""; + } + } else { + if (isEqual(route?.query, item?.query)) { + return "is-active"; + } else { + return ""; + } + } + }; +}); + +const scheduleIsActive = computed(() => { + return item => { + if (Object.keys(route.query).length === 0) { + if (route.path === item.path) { + return "schedule-active"; + } else { + return ""; + } + } else { + if (isEqual(route?.query, item?.query)) { + return "schedule-active"; + } else { + return ""; + } + } + }; +}); + +const iconIsActive = computed(() => { + return (item, index) => { + if (index === 0) return; + if (Object.keys(route.query).length === 0) { + if (route.path === item.path) { + return true; + } else { + return false; + } + } else { + if (isEqual(route?.query, item?.query)) { + return true; + } else { + return false; + } + } + }; +}); + const dynamicTagView = () => { const index = multiTags.value.findIndex(item => { return item.path === route.path; @@ -229,7 +285,13 @@ function deleteDynamicTag(obj: any, current: any, tag?: string) { // 存放被删除的缓存路由 let delAliveRouteList = []; let valueIndex: number = multiTags.value.findIndex((item: any) => { - return item.path === obj.path; + if (item.query) { + if (item.path === obj.path) { + return item.query === obj.query; + } + } else { + return item.path === obj.path; + } }); const spliceRoute = ( @@ -280,7 +342,8 @@ function deleteDynamicTag(obj: any, current: any, tag?: string) { if (tag === "left") return; nextTick(() => { router.push({ - path: newRoute[0].path + path: newRoute[0].path, + query: newRoute[0].query }); }); } else { @@ -292,7 +355,8 @@ function deleteDynamicTag(obj: any, current: any, tag?: string) { }); !isHasActiveTag && router.push({ - path: newRoute[0].path + path: newRoute[0].path, + query: newRoute[0].query }); } } @@ -478,7 +542,8 @@ function openMenu(tag, e) { // 触发tags标签切换 function tagOnClick(item) { router.push({ - path: item?.path + path: item?.path, + query: item?.query }); showMenuModel(item?.path); } @@ -564,7 +629,7 @@ onBeforeMount(() => { :key="index" :class="[ 'scroll-item is-closable', - $route.path === item.path ? 'is-active' : '', + linkIsActive(item), $route.path === item.path && showModel === 'card' ? 'card-active' : '' @@ -574,12 +639,12 @@ onBeforeMount(() => { @mouseleave.prevent="onMouseleave(item, index)" @click="tagOnClick(item)" > - {{ - transformI18n(item.meta.title, item.meta.i18n) - }} + {{ transformI18n(item.meta.title, item.meta.i18n) }} + {
diff --git a/src/layout/types.ts b/src/layout/types.ts index 2a25b85eb..72c7f8731 100644 --- a/src/layout/types.ts +++ b/src/layout/types.ts @@ -14,6 +14,7 @@ export const routerArrays: Array = [ export type RouteConfigs = { path?: string; parentPath?: string; + query?: object; meta?: { title?: string; i18n?: boolean; diff --git a/src/router/index.ts b/src/router/index.ts index cb6a9924e..e714dce7e 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,14 +1,14 @@ -import { Router, RouteMeta, createRouter, RouteRecordName } from "vue-router"; import { toRouteType } from "./types"; import { openLink } from "/@/utils/link"; import NProgress from "/@/utils/progress"; -import { split, uniqBy, find, findIndex } from "lodash-es"; import { constantRoutes } from "./modules"; import { transformI18n } from "/@/plugins/i18n"; import remainingRouter from "./modules/remaining"; +import { split, find, findIndex } from "lodash-es"; import { storageSession, storageLocal } from "/@/utils/storage"; import { useMultiTagsStoreHook } from "/@/store/modules/multiTags"; import { usePermissionStoreHook } from "/@/store/modules/permission"; +import { Router, RouteMeta, createRouter, RouteRecordName } from "vue-router"; import { initRouter, getHistoryMode, @@ -138,7 +138,7 @@ router.beforeEach((to: toRouteType, _from, next) => { router.push(to.fullPath); // 刷新页面更新标签栏与页面路由匹配 const localRoutes = storageLocal.getItem("responsive-tags"); - const home = find(router.options?.routes, function (route) { + const home = find(router.options?.routes, route => { return route.path === "/"; }); const optionsRoutes = [home, ...router.options?.routes[0].children]; @@ -150,10 +150,6 @@ router.beforeEach((to: toRouteType, _from, next) => { } }); }); - storageLocal.setItem( - "responsive-tags", - uniqBy(newLocalRoutes, "path") - ); }); next(); } diff --git a/src/store/modules/multiTags.ts b/src/store/modules/multiTags.ts index e6420aae2..4ad05296b 100644 --- a/src/store/modules/multiTags.ts +++ b/src/store/modules/multiTags.ts @@ -1,5 +1,6 @@ import { defineStore } from "pinia"; import { store } from "/@/store"; +import { isEqual } from "lodash-es"; import { storageLocal } from "/@/utils/storage"; import { multiType, positionType } from "./types"; @@ -54,12 +55,18 @@ export const useMultiTagsStore = defineStore({ case "push": { const tagVal = value as multiType; - // 判断tag是否已存在: + // 判断tag是否已存在 const tagHasExits = this.multiTags.some(tag => { return tag.path === tagVal?.path; }); - if (tagHasExits && !tagVal.query) return; + // 判断tag中的query键值是否相等 + const tagQueryHasExits = this.multiTags.some(tag => { + return isEqual(tag.query, tagVal.query); + }); + + if (tagHasExits && tagQueryHasExits) return; + const meta = tagVal?.meta; const dynamicLevel = meta?.dynamicLevel ?? -1; if (dynamicLevel > 0) { @@ -85,10 +92,8 @@ export const useMultiTagsStore = defineStore({ this.multiTags.splice(position?.startIndex, position?.length); this.tagsCache(this.multiTags); return this.multiTags; - break; case "slice": return this.multiTags.slice(-1); - break; } } } diff --git a/src/views/tabs/index/index.vue b/src/views/tabs/index/index.vue index 63178d7d2..1e0cd3cd4 100644 --- a/src/views/tabs/index/index.vue +++ b/src/views/tabs/index/index.vue @@ -12,7 +12,7 @@ function toDetail(index: number) { path: `/tabs/detail`, parentPath: route.matched[0].path, name: "tabDetail", - query: { id: index }, + query: { id: String(index) }, meta: { title: { zh: `No.${index} - 详情信息`, en: `No.${index} - DetailInfo` }, showLink: false, @@ -21,7 +21,7 @@ function toDetail(index: number) { realPath: "/tabs/detail" } }); - router.push({ name: "tabDetail", query: { id: index } }); + router.push({ name: "tabDetail", query: { id: String(index) } }); }