Jelajahi Sumber

✨ feat:TagsView 支持多个 path 相同但 fullPath 不相同情况。

preschooler 9 bulan lalu
induk
melakukan
a401d8ede4

+ 6 - 7
src/layout/components/TagsView/src/TagsView.vue

@@ -127,12 +127,8 @@ const toLastView = () => {
 const moveToCurrentTag = async () => {
   await nextTick()
   for (const v of unref(visitedViews)) {
-    if (v.fullPath === unref(currentRoute).path) {
+    if (v.fullPath === unref(currentRoute).fullPath) {
       moveToTarget(v)
-      if (v.fullPath !== unref(currentRoute).fullPath) {
-        tagsViewStore.updateVisitedView(unref(currentRoute))
-      }
-
       break
     }
   }
@@ -207,7 +203,7 @@ const moveToTarget = (currentTag: RouteLocationNormalizedLoaded) => {
 
 // 是否是当前tag
 const isActive = (route: RouteLocationNormalizedLoaded): boolean => {
-  return route.path === unref(currentRoute).path
+  return route.fullPath === unref(currentRoute).fullPath
 }
 
 // 所有右键菜单组件的元素
@@ -373,7 +369,10 @@ watch(
                     :size="12"
                     class="mr-5px"
                   />
-                  {{ t(item?.meta?.title as string) }}
+                  {{
+                    t(item?.meta?.title as string) +
+                    (item?.meta?.titleSuffix ? ` (${item?.meta?.titleSuffix})` : '')
+                  }}
                   <Icon
                     :class="`${prefixCls}__item--close`"
                     :size="12"

+ 26 - 12
src/store/modules/tagsView.ts

@@ -31,13 +31,27 @@ export const useTagsViewStore = defineStore('tagsView', {
     },
     // 新增tag
     addVisitedView(view: RouteLocationNormalizedLoaded) {
-      if (this.visitedViews.some((v) => v.path === view.path)) return
+      if (this.visitedViews.some((v) => v.fullPath === view.fullPath)) return
       if (view.meta?.noTagsView) return
-      this.visitedViews.push(
-        Object.assign({}, view, {
-          title: view.meta?.title || 'no-name'
+      const visitedView = Object.assign({}, view, { title: view.meta?.title || 'no-name' })
+
+      if (visitedView.meta) {
+        const titleSuffixList: string[] = []
+        this.visitedViews.forEach((v) => {
+          if (v.path === visitedView.path && v.meta?.title === visitedView.meta?.title) {
+            titleSuffixList.push(v.meta?.titleSuffix || '1')
+          }
         })
-      )
+        if (titleSuffixList.length) {
+          let titleSuffix = 1
+          while (titleSuffixList.includes(`${titleSuffix}`)) {
+            titleSuffix += 1
+          }
+          visitedView.meta.titleSuffix = titleSuffix === 1 ? undefined : `${titleSuffix}`
+        }
+      }
+
+      this.visitedViews.push(visitedView)
     },
     // 新增缓存
     addCachedView() {
@@ -63,7 +77,7 @@ export const useTagsViewStore = defineStore('tagsView', {
     // 删除tag
     delVisitedView(view: RouteLocationNormalizedLoaded) {
       for (const [i, v] of this.visitedViews.entries()) {
-        if (v.path === view.path) {
+        if (v.fullPath === view.fullPath) {
           this.visitedViews.splice(i, 1)
           break
         }
@@ -95,18 +109,18 @@ export const useTagsViewStore = defineStore('tagsView', {
     // 删除其他tag
     delOthersVisitedViews(view: RouteLocationNormalizedLoaded) {
       this.visitedViews = this.visitedViews.filter((v) => {
-        return v?.meta?.affix || v.path === view.path
+        return v?.meta?.affix || v.fullPath === view.fullPath
       })
     },
     // 删除左侧
     delLeftViews(view: RouteLocationNormalizedLoaded) {
       const index = findIndex<RouteLocationNormalizedLoaded>(
         this.visitedViews,
-        (v) => v.path === view.path
+        (v) => v.fullPath === view.fullPath
       )
       if (index > -1) {
         this.visitedViews = this.visitedViews.filter((v, i) => {
-          return v?.meta?.affix || v.path === view.path || i > index
+          return v?.meta?.affix || v.fullPath === view.fullPath || i > index
         })
         this.addCachedView()
       }
@@ -115,18 +129,18 @@ export const useTagsViewStore = defineStore('tagsView', {
     delRightViews(view: RouteLocationNormalizedLoaded) {
       const index = findIndex<RouteLocationNormalizedLoaded>(
         this.visitedViews,
-        (v) => v.path === view.path
+        (v) => v.fullPath === view.fullPath
       )
       if (index > -1) {
         this.visitedViews = this.visitedViews.filter((v, i) => {
-          return v?.meta?.affix || v.path === view.path || i < index
+          return v?.meta?.affix || v.fullPath === view.fullPath || i < index
         })
         this.addCachedView()
       }
     },
     updateVisitedView(view: RouteLocationNormalizedLoaded) {
       for (let v of this.visitedViews) {
-        if (v.path === view.path) {
+        if (v.fullPath === view.fullPath) {
           v = Object.assign(v, view)
           break
         }

+ 3 - 0
types/router.d.ts

@@ -15,6 +15,8 @@ import { defineComponent } from 'vue'
 
     title: 'title'            设置该路由在侧边栏和面包屑中展示的名字
 
+    titleSuffix: '2'          当 path 和 title 重复时的后缀或备注
+
     icon: 'svg-name'          设置该路由的图标
 
     noCache: true             如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
@@ -37,6 +39,7 @@ declare module 'vue-router' {
     hidden?: boolean
     alwaysShow?: boolean
     title?: string
+    titleSuffix?: string
     icon?: string
     noCache?: boolean
     breadcrumb?: boolean