modify: support multi tabs

This commit is contained in:
chansee97 2024-10-08 12:37:27 +08:00
parent 308e0b4bf9
commit e7148081a9
6 changed files with 65 additions and 42 deletions

View File

@ -16,10 +16,7 @@ const appStore = useAppStore()
const router = useRouter()
function handleTab(route: RouteLocationNormalized) {
router.push(route.path)
}
function handleClose(path: string) {
tabStore.closeTab(path)
router.push(route.fullPath)
}
const { t } = useI18n()
const options = computed(() => {
@ -71,16 +68,16 @@ function handleSelect(key: string) {
appStore.reloadPage()
},
closeCurrent() {
tabStore.closeTab(currentRoute.value.path)
tabStore.closeTab(currentRoute.value.fullPath)
},
closeOther() {
tabStore.closeOtherTabs(currentRoute.value.path)
tabStore.closeOtherTabs(currentRoute.value.fullPath)
},
closeLeft() {
tabStore.closeLeftTabs(currentRoute.value.path)
tabStore.closeLeftTabs(currentRoute.value.fullPath)
},
closeRight() {
tabStore.closeRightTabs(currentRoute.value.path)
tabStore.closeRightTabs(currentRoute.value.fullPath)
},
closeAll() {
tabStore.closeAllTabs()
@ -110,13 +107,13 @@ function onClickoutside() {
size="small"
:tabs-padding="10"
:value="tabStore.currentTabPath"
@close="handleClose"
@close="tabStore.closeTab"
>
<n-tab
v-for="item in tabStore.pinTabs"
:key="item.path"
:name="item.path"
@click="router.push(item.path)"
:key="item.fullPath"
:name="item.fullPath"
@click="router.push(item.fullPath)"
>
<div class="flex-x-center gap-2">
<nova-icon :icon="item.meta.icon" /> {{ $t(`route.${String(item.name)}`, item.meta.title) }}
@ -124,9 +121,9 @@ function onClickoutside() {
</n-tab>
<n-tab
v-for="item in tabStore.tabs"
:key="item.path"
:key="item.fullPath"
closable
:name="item.path"
:name="item.fullPath"
@click="handleTab(item)"
@contextmenu="handleContextMenu($event, item)"
>

View File

@ -61,7 +61,7 @@ export function setupRouterGuard(router: Router) {
// 添加tabs
tabStore.addTab(to)
// 设置高亮标签;
tabStore.setCurrentTab(to.path as string)
tabStore.setCurrentTab(to.fullPath as string)
})
router.afterEach((to) => {

View File

@ -58,7 +58,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
{
name: 'multi2Detail',
path: '/multi/multi2/detail',
title: '多级菜单详情页',
title: '菜单详情页',
requiresAuth: true,
icon: 'icon-park-outline:list',
hide: true,

View File

@ -24,7 +24,7 @@ export const useTabStore = defineStore('tab-store', {
return
// 如果标签名称已存在则不添加
if (this.hasExistTab(route.path as string))
if (this.hasExistTab(route.fullPath as string))
return
// 根据meta.pinTab传递到不同的分组中
@ -33,42 +33,42 @@ export const useTabStore = defineStore('tab-store', {
else
this.tabs.push(route)
},
async closeTab(path: string) {
async closeTab(fullPath: string) {
const tabsLength = this.tabs.length
// 如果动态标签大于一个,才会标签跳转
if (this.tabs.length > 1) {
// 获取关闭的标签索引
const index = this.getTabIndex(path)
const index = this.getTabIndex(fullPath)
const isLast = index + 1 === tabsLength
// 如果是关闭的当前页面,路由跳转到原先标签的后一个标签
if (this.currentTabPath === path && !isLast) {
if (this.currentTabPath === fullPath && !isLast) {
// 跳转到后一个标签
router.push(this.tabs[index + 1].path)
router.push(this.tabs[index + 1].fullPath)
}
else if (this.currentTabPath === path && isLast) {
else if (this.currentTabPath === fullPath && isLast) {
// 已经是最后一个了,就跳转前一个
router.push(this.tabs[index - 1].path)
router.push(this.tabs[index - 1].fullPath)
}
}
// 删除标签
this.tabs = this.tabs.filter((item) => {
return item.path !== path
return item.fullPath !== fullPath
})
// 删除后如果清空了,就跳转到默认首页
if (tabsLength - 1 === 0)
router.push('/')
},
closeOtherTabs(path: string) {
const index = this.getTabIndex(path)
closeOtherTabs(fullPath: string) {
const index = this.getTabIndex(fullPath)
this.tabs = this.tabs.filter((item, i) => i === index)
},
closeLeftTabs(path: string) {
const index = this.getTabIndex(path)
closeLeftTabs(fullPath: string) {
const index = this.getTabIndex(fullPath)
this.tabs = this.tabs.filter((item, i) => i >= index)
},
closeRightTabs(path: string) {
const index = this.getTabIndex(path)
closeRightTabs(fullPath: string) {
const index = this.getTabIndex(fullPath)
this.tabs = this.tabs.filter((item, i) => i <= index)
},
clearAllTabs() {
@ -80,21 +80,25 @@ export const useTabStore = defineStore('tab-store', {
router.push('/')
},
hasExistTab(path: string) {
hasExistTab(fullPath: string) {
const _tabs = [...this.tabs, ...this.pinTabs]
return _tabs.some((item) => {
return item.path === path
return item.fullPath === fullPath
})
},
/* 设置当前激活的标签 */
setCurrentTab(path: string) {
this.currentTabPath = path
setCurrentTab(fullPath: string) {
this.currentTabPath = fullPath
},
getTabIndex(path: string) {
getTabIndex(fullPath: string) {
return this.tabs.findIndex((item) => {
return item.path === path
return item.fullPath === fullPath
})
},
modifyTab(fullPath: string, modifyFn: (route: RouteLocationNormalized) => void) {
const index = this.getTabIndex(fullPath)
modifyFn(this.tabs[index])
},
},
persist: {
storage: sessionStorage,

View File

@ -1,9 +1,25 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import { useTabStore } from '@/store'
const { modifyTab } = useTabStore()
const { fullPath, query } = useRoute()
modifyTab(fullPath, (target) => {
target.meta.title = `详情页${query.id}`
})
</script>
<template>
<n-alert title="目前可公开的情报" type="warning">
这是详情子页他不会出现在侧边栏,他其实是上个页面的同级并不是下级这个要注意
</n-alert>
<n-space vertical>
<n-alert title="目前可公开的情报" type="warning">
这是详情子页他不会出现在侧边栏,他其实是上个页面的同级并不是下级这个要注意
</n-alert>
<n-h2>
详情页id:{{ query.id }}
</n-h2>
</n-space>
</template>
<style scoped></style>

View File

@ -5,8 +5,14 @@ const router = useRouter()
<template>
<n-card class="h-130vh">
这个页面包含了一个不在侧边菜单的详情页面
<n-button @click="router.push('/multi/multi2/detail')">
跳转详情子页
<n-button @click="router.push({ path: '/multi/multi2/detail', query: { id: 1 } })">
跳转详情子页1
</n-button>
<n-button @click="router.push({ path: '/multi/multi2/detail', query: { id: 2 } })">
跳转详情子页2
</n-button>
<n-button @click="router.push({ path: '/multi/multi2/detail', query: { id: 3 } })">
跳转详情子页3
</n-button>
</n-card>
</template>