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

pull/570/head
preschooler 2024-10-22 17:19:55 +08:00
parent a31bafbb4a
commit a401d8ede4
3 changed files with 35 additions and 19 deletions

View File

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

View File

@ -31,13 +31,27 @@ export const useTagsViewStore = defineStore('tagsView', {
}, },
// 新增tag // 新增tag
addVisitedView(view: RouteLocationNormalizedLoaded) { 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 if (view.meta?.noTagsView) return
this.visitedViews.push( const visitedView = Object.assign({}, view, { title: view.meta?.title || 'no-name' })
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() { addCachedView() {
@ -63,7 +77,7 @@ export const useTagsViewStore = defineStore('tagsView', {
// 删除tag // 删除tag
delVisitedView(view: RouteLocationNormalizedLoaded) { delVisitedView(view: RouteLocationNormalizedLoaded) {
for (const [i, v] of this.visitedViews.entries()) { for (const [i, v] of this.visitedViews.entries()) {
if (v.path === view.path) { if (v.fullPath === view.fullPath) {
this.visitedViews.splice(i, 1) this.visitedViews.splice(i, 1)
break break
} }
@ -95,18 +109,18 @@ export const useTagsViewStore = defineStore('tagsView', {
// 删除其他tag // 删除其他tag
delOthersVisitedViews(view: RouteLocationNormalizedLoaded) { delOthersVisitedViews(view: RouteLocationNormalizedLoaded) {
this.visitedViews = this.visitedViews.filter((v) => { 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) { delLeftViews(view: RouteLocationNormalizedLoaded) {
const index = findIndex<RouteLocationNormalizedLoaded>( const index = findIndex<RouteLocationNormalizedLoaded>(
this.visitedViews, this.visitedViews,
(v) => v.path === view.path (v) => v.fullPath === view.fullPath
) )
if (index > -1) { if (index > -1) {
this.visitedViews = this.visitedViews.filter((v, i) => { 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() this.addCachedView()
} }
@ -115,18 +129,18 @@ export const useTagsViewStore = defineStore('tagsView', {
delRightViews(view: RouteLocationNormalizedLoaded) { delRightViews(view: RouteLocationNormalizedLoaded) {
const index = findIndex<RouteLocationNormalizedLoaded>( const index = findIndex<RouteLocationNormalizedLoaded>(
this.visitedViews, this.visitedViews,
(v) => v.path === view.path (v) => v.fullPath === view.fullPath
) )
if (index > -1) { if (index > -1) {
this.visitedViews = this.visitedViews.filter((v, i) => { 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() this.addCachedView()
} }
}, },
updateVisitedView(view: RouteLocationNormalizedLoaded) { updateVisitedView(view: RouteLocationNormalizedLoaded) {
for (let v of this.visitedViews) { for (let v of this.visitedViews) {
if (v.path === view.path) { if (v.fullPath === view.fullPath) {
v = Object.assign(v, view) v = Object.assign(v, view)
break break
} }

3
types/router.d.ts vendored
View File

@ -15,6 +15,8 @@ import { defineComponent } from 'vue'
title: 'title' title: 'title'
titleSuffix: '2' path title
icon: 'svg-name' icon: 'svg-name'
noCache: true true <keep-alive> ( false) noCache: true true <keep-alive> ( false)
@ -37,6 +39,7 @@ declare module 'vue-router' {
hidden?: boolean hidden?: boolean
alwaysShow?: boolean alwaysShow?: boolean
title?: string title?: string
titleSuffix?: string
icon?: string icon?: string
noCache?: boolean noCache?: boolean
breadcrumb?: boolean breadcrumb?: boolean