feat(components): 完善了动态tabs的逻辑处理

This commit is contained in:
Coffee-crocodile 2022-08-19 14:05:00 +08:00
parent 30ef04efe3
commit 518689f64d
4 changed files with 94 additions and 8 deletions

View File

@ -21,7 +21,7 @@
<UserCenter />
</div>
</n-layout-header>
<n-layout-header bordered class="h-45px"><TabBar /></n-layout-header>
<n-layout-header class="h-45px"><TabBar /></n-layout-header>
<div class="p-16px">
<n-layout-content class="bg-transparent">
<router-view v-slot="{ Component }">

View File

@ -1,24 +1,37 @@
<template>
<div class="wh-full px-3 flex items-end">
<n-tabs type="card" size="small">
<n-tab name="幸福">工作台</n-tab>
<n-tab v-for="item in tabStore.tabs" :key="item.path" closable :name="item.meta.title" @click="handleTab(item)">
<div class="wh-full flex items-end">
<n-tabs type="card" size="small" :tabs-padding="15" :value="tabStore.currentTab" @close="handleClose">
<n-tab v-for="item in tabStore.inherentTab" :key="item.path" :name="item.name" @click="toRoot">
{{ item.title }}
</n-tab>
<n-tab
v-for="item in tabStore.tabs"
:key="item.path"
closable
:name="item.name as string"
@click="handleTab(item)"
>
{{ item.meta.title }}
</n-tab>
</n-tabs>
</div>
</template>
<script setup lang="ts">
<script lang="ts" setup>
import { useTabStore } from '@/store';
import { useAppRouter } from '~/src/hook';
import { RouteLocationNormalized } from 'vue-router';
import { defineComponent } from 'vue';
const tabStore = useTabStore();
const { routerPush } = useAppRouter();
const { routerPush, toRoot } = useAppRouter();
const handleTab = (route: RouteLocationNormalized) => {
routerPush(route.path);
};
const handleClose = (name: string) => {
tabStore.closeTab(name);
};
</script>
<style scoped></style>

View File

@ -42,7 +42,10 @@ export async function createPermissionGuard(
} else {
routeStore.setActiveMenu(to.fullPath);
}
// 添加动态tabs
// 添加tabs
tabStore.addTab(to);
// 设置高亮标签;
tabStore.setCurrentTab(to.name as string);
next();
}

View File

@ -1,18 +1,88 @@
import { defineStore } from 'pinia';
import { RouteLocationNormalized } from 'vue-router';
import { useAppRouter } from '@/hook';
interface TabState {
inherentTab: {
name: string;
title: string;
path: string;
}[];
tabs: RouteLocationNormalized[];
currentTab: string;
}
export const useTabStore = defineStore('tab-store', {
state: (): TabState => {
return {
inherentTab: [
{
name: 'dashboard_workbench',
title: '工作台',
path: '/',
},
],
tabs: [],
currentTab: 'dashboard_workbench',
};
},
getters: {
inherentTabName(): string[] {
return this.inherentTab.map((item) => {
return item.name;
});
},
},
actions: {
addTab(route: RouteLocationNormalized) {
// 如果已经在固有标签里则不添加
if (this.inherentTabName.includes(route.name as string)) {
return;
}
// 如果标签名称已存在则不添加
if (this.hasExistTab(route.name as string)) {
return;
}
this.tabs.push(route);
},
closeTab(name: string) {
const { routerPush, toRoot } = useAppRouter(false);
const tabsLength = this.tabs.length;
// 如果动态标签大于一个,才会标签跳转
if (this.tabs.length > 1) {
// 获取关闭的标签索引
const index = this.getTabIndex(name);
const isLast = index + 1 === tabsLength;
// 如果是关闭的当前页面,路由跳转到原先标签的后一个标签
if (this.currentTab === name && !isLast) {
// 跳转到后一个标签
routerPush(this.tabs[index + 1].path);
} else {
// 已经是最后一个了,就跳转前一个
routerPush(this.tabs[index - 1].path);
}
}
// 删除标签
this.tabs = this.tabs.filter((item) => {
return item.name !== name;
});
// 删除后如果清空了,就跳转到默认首页
if (tabsLength - 1 === 0) {
toRoot();
}
},
hasExistTab(name: string) {
return this.tabs.some((item) => {
return item.name === name;
});
},
/* 设置当前激活的标签 */
setCurrentTab(name: string) {
this.currentTab = name;
},
getTabIndex(name: string) {
return this.tabs.findIndex((item) => {
return item.name === name;
});
},
},
});