需求:
- 打开的页面标签显示在标签栏中
- 点击标签栏跳转到对应页面
- 关闭标签栏的是当前打开的页面,则关闭当前页面,打开最后一个标签栏对应页面;如果关闭的标签栏不是打开页面,则直接关掉该标签栏
思路:
- 用pinia记录打开的路由列表
- 用el-tag根据pinia中记录的路由列表渲染标签栏
- 设置路由守卫,判断跳转的页面路由是否已经记录在pinia中,如果没记录,则进行添加;如果有则不进行操作
- 关闭标签栏则将该路由从pinia中删除
实现
- 在pinia中记录访问过的路由,和默认打开的页面路由
//路由标签页
let activeRoute = {
path: '/BackendHome',
name: '首页',
};
let visitedRoutes=reactive([activeRoute]) ;
-
因为只有后台相关的路由才需要存入visitedRoutes,所以给相关路由的meta添加属性record,用于判断是否该路由是否需要存入visitedRoutes
-
添加路由守卫,判断跳转的路由是否需要存入visitedRoutes中,且visitedRoutes是否已经存在该路由,如果不存在则加入visitedRoutes中,已经存在则返回
router.afterEach((to)=>{
if(to.meta.record){
const userMsg = userStore();
let routerHas = userMsg.visitedRoutes.findIndex((val)=>{
return val.name === to.name
})
if(routerHas == -1){
userMsg.visitedRoutes.push({path:to.path,name:to.name});
}else{
return
}
}else{
return
}
})
- 将标签栏封装为组件,存放在 src\components\backComponents\Tags.vue,写入下面代码。
读取visitedRoutes中的数据用于渲染tag。打开新的页面则标签页增加;点击标签页则跳转到相应页面;关闭标签页,则删除visitedRoutes中对应路由,并判断关闭的标签页是否是当前活跃的页面,如果是则关闭当前页面,并打开visitedRoutes最后一个页面。
<template>
<div class="tags">
<el-tag v-for="item in userMsg.visitedRoutes"
:key="item.name"
:closable="item.name != '首页'"
type="warning"
:disable-transitions="false"
@close="closeTag(item.name)"
@click="goToRoute(item.path)"
>
{{ item.name }}
</el-tag>
</div>
</template>
<script setup lang="ts">
import {useRouter, useRoute} from 'vue-router'
import {userStore} from '../../stores'
const userMsg = userStore();
//全局路由
const router = useRouter();
//当前活跃的路由
const route = useRoute();
//关闭标签页
const closeTag = (name:string)=>{
console.log('关闭',name);
if(name == '首页'){
return
}else{
userMsg.deleteTAb(name);
if(route.name == name){
let routeLength = userMsg.visitedRoutes.length;
if(userMsg.visitedRoutes && routeLength >= 1 ){
router.push(userMsg.visitedRoutes[routeLength-1]);
}
}
}
}
//点击标签页
const goToRoute = (path:string)=>{
router.push(path);
}
</script>
<style scoped>
</style>
在pinia中添加相应删除标签页方法
//删除标签页
const deleteTAb = (tabName:string)=>{
//获取要删除的路由下标
let tabIndex = visitedRoutes.findIndex((val)=>{
return val.name == tabName
})
if(tabIndex != -1){
visitedRoutes.splice(tabIndex,1);
}
}
- 最后引入组件
最终效果如下