✨ feat:TagsView 支持多个 path 相同但 fullPath 不相同情况。
parent
a31bafbb4a
commit
a401d8ede4
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue