封装为一个组件
<template>
<div class="TagPage">
<el-tabs type="border-card"
v-model="activeTab" :closable="editableTabs.length > 1"
@tab-click="handleTabClick"
@tab-remove="handleTabRemove">
<el-tab-pane v-for="tab in editableTabs" :key="tab.name"
:label="tab.title" :name="tab.name">
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup>
import { ref, watch } from 'vue'
// 路由
import { useRoute, useRouter } from 'vue-router'
// pinia
import { useTagStore } from '@/stores/modules/tag.js'
const store = useTagStore()
const route = useRoute()
const router = useRouter()
// 展示的标签页 v-model绑定的值
const activeTab = ref('')
// 可选标签页
const editableTabs = ref([])
// 第一次打开网页初始化pinia中存储的标签页
if (window.performance.navigation.type !== 1) store.addTag([])
// 选中标签页的事件 (路由跳转到选中的标签页)
const handleTabClick = (tab) => {
router.push(tab.props.name)
}
// 删除标签页
const handleTabRemove = (targetName) => {
// filter循环找到未删除的标签页重新赋值给可选标签页
editableTabs.value = editableTabs.value.filter(
(tab) => tab.name !== targetName
)
// 获取最后一个标签并跳转到最后一个标签页并给展示的标签页赋值
const lastTab = editableTabs.value[editableTabs.value.length - 1]
activeTab.value = lastTab ? lastTab.name : ''
router.push(activeTab.value)
// 同时删除pinia中存储的标签页
store.delTag(targetName)
}
// 通过watch监听来获得用户点击过的标签页
watch(() => route,(newVal) => {
// 先访问pinia中是否存储的有标签页信息(有则展示,无则将可选标签页赋值为空数组)
editableTabs.value = store.tagList.length ? store.tagList : []
// 判断路由跳转的页面是否已在可选标签页数据中
const isNewTab = !editableTabs.value.some((tab) => tab.name === newVal.path)
// 如果不在进行以下操作
if (isNewTab) {
/* 这里我是给标签页的长度做出了限制,最多有六个标签页,如果超出六个标签页
则删除第一个标签页,若第一个标签页是选中状态,则删除第二个。 */
if (editableTabs.value.length > 5) {
const indexToRemove = activeTab.value !== newVal.path ? 1 : 0
editableTabs.value.splice(indexToRemove, 1)
}
// 将标签页存储到可选择标签页中并存储到pinia中
editableTabs.value.push({
name: newVal.path,
title: newVal.meta.title,
content: newVal.meta.title
})
store.addTag(editableTabs.value)
}
activeTab.value = newVal.path
},{ deep: true, immediate: true })
</script>
<style scoped lang="scss">
.TagPage {
width: 100%;
height: 40px;
margin-bottom: 13px;
overflow: hidden;
}
:deep(.el-tabs__content) {
padding: 0;
height: 0;
}
</style>
为什么要存到pinia:
pinia做了数据持久化处理,存到pinia是为了防止刷新标签页丢失,也可以通过localStorage存到本地。
总结:
综合思路:通过watch监听路由变化然后将监听到的路由保存起来通过增删来实现标签页的切换。
有问题或疑惑请留言或者私信邮箱:zh_brave@163.com