Skip to content

Commit a401d8e

Browse files
✨ feat:TagsView 支持多个 path 相同但 fullPath 不相同情况。
1 parent a31bafb commit a401d8e

File tree

3 files changed

+35
-19
lines changed

3 files changed

+35
-19
lines changed

src/layout/components/TagsView/src/TagsView.vue

+6-7
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,8 @@ const toLastView = () => {
127127
const moveToCurrentTag = async () => {
128128
await nextTick()
129129
for (const v of unref(visitedViews)) {
130-
if (v.fullPath === unref(currentRoute).path) {
130+
if (v.fullPath === unref(currentRoute).fullPath) {
131131
moveToTarget(v)
132-
if (v.fullPath !== unref(currentRoute).fullPath) {
133-
tagsViewStore.updateVisitedView(unref(currentRoute))
134-
}
135-
136132
break
137133
}
138134
}
@@ -207,7 +203,7 @@ const moveToTarget = (currentTag: RouteLocationNormalizedLoaded) => {
207203
208204
// 是否是当前tag
209205
const isActive = (route: RouteLocationNormalizedLoaded): boolean => {
210-
return route.path === unref(currentRoute).path
206+
return route.fullPath === unref(currentRoute).fullPath
211207
}
212208
213209
// 所有右键菜单组件的元素
@@ -373,7 +369,10 @@ watch(
373369
:size="12"
374370
class="mr-5px"
375371
/>
376-
{{ t(item?.meta?.title as string) }}
372+
{{
373+
t(item?.meta?.title as string) +
374+
(item?.meta?.titleSuffix ? ` (${item?.meta?.titleSuffix})` : '')
375+
}}
377376
<Icon
378377
:class="`${prefixCls}__item--close`"
379378
:size="12"

src/store/modules/tagsView.ts

+26-12
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,27 @@ export const useTagsViewStore = defineStore('tagsView', {
3131
},
3232
// 新增tag
3333
addVisitedView(view: RouteLocationNormalizedLoaded) {
34-
if (this.visitedViews.some((v) => v.path === view.path)) return
34+
if (this.visitedViews.some((v) => v.fullPath === view.fullPath)) return
3535
if (view.meta?.noTagsView) return
36-
this.visitedViews.push(
37-
Object.assign({}, view, {
38-
title: view.meta?.title || 'no-name'
36+
const visitedView = Object.assign({}, view, { title: view.meta?.title || 'no-name' })
37+
38+
if (visitedView.meta) {
39+
const titleSuffixList: string[] = []
40+
this.visitedViews.forEach((v) => {
41+
if (v.path === visitedView.path && v.meta?.title === visitedView.meta?.title) {
42+
titleSuffixList.push(v.meta?.titleSuffix || '1')
43+
}
3944
})
40-
)
45+
if (titleSuffixList.length) {
46+
let titleSuffix = 1
47+
while (titleSuffixList.includes(`${titleSuffix}`)) {
48+
titleSuffix += 1
49+
}
50+
visitedView.meta.titleSuffix = titleSuffix === 1 ? undefined : `${titleSuffix}`
51+
}
52+
}
53+
54+
this.visitedViews.push(visitedView)
4155
},
4256
// 新增缓存
4357
addCachedView() {
@@ -63,7 +77,7 @@ export const useTagsViewStore = defineStore('tagsView', {
6377
// 删除tag
6478
delVisitedView(view: RouteLocationNormalizedLoaded) {
6579
for (const [i, v] of this.visitedViews.entries()) {
66-
if (v.path === view.path) {
80+
if (v.fullPath === view.fullPath) {
6781
this.visitedViews.splice(i, 1)
6882
break
6983
}
@@ -95,18 +109,18 @@ export const useTagsViewStore = defineStore('tagsView', {
95109
// 删除其他tag
96110
delOthersVisitedViews(view: RouteLocationNormalizedLoaded) {
97111
this.visitedViews = this.visitedViews.filter((v) => {
98-
return v?.meta?.affix || v.path === view.path
112+
return v?.meta?.affix || v.fullPath === view.fullPath
99113
})
100114
},
101115
// 删除左侧
102116
delLeftViews(view: RouteLocationNormalizedLoaded) {
103117
const index = findIndex<RouteLocationNormalizedLoaded>(
104118
this.visitedViews,
105-
(v) => v.path === view.path
119+
(v) => v.fullPath === view.fullPath
106120
)
107121
if (index > -1) {
108122
this.visitedViews = this.visitedViews.filter((v, i) => {
109-
return v?.meta?.affix || v.path === view.path || i > index
123+
return v?.meta?.affix || v.fullPath === view.fullPath || i > index
110124
})
111125
this.addCachedView()
112126
}
@@ -115,18 +129,18 @@ export const useTagsViewStore = defineStore('tagsView', {
115129
delRightViews(view: RouteLocationNormalizedLoaded) {
116130
const index = findIndex<RouteLocationNormalizedLoaded>(
117131
this.visitedViews,
118-
(v) => v.path === view.path
132+
(v) => v.fullPath === view.fullPath
119133
)
120134
if (index > -1) {
121135
this.visitedViews = this.visitedViews.filter((v, i) => {
122-
return v?.meta?.affix || v.path === view.path || i < index
136+
return v?.meta?.affix || v.fullPath === view.fullPath || i < index
123137
})
124138
this.addCachedView()
125139
}
126140
},
127141
updateVisitedView(view: RouteLocationNormalizedLoaded) {
128142
for (let v of this.visitedViews) {
129-
if (v.path === view.path) {
143+
if (v.fullPath === view.fullPath) {
130144
v = Object.assign(v, view)
131145
break
132146
}

types/router.d.ts

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

0 commit comments

Comments
 (0)