技术:vue2+vuex+elementui
store/index.js文件里
import Vuefrom'vue'import Vuexfrom'vuex'
Vue.use(Vuex)exportdefaultnewVuex.Store({
state:{
tabList:[]},
mutations:{addTab:(state, tab)=>{// 如果tab已经存在,不添加新的tabsif(state.tabList.some(item=> item.path=== tab.path))return
state.tabList.push(tab)}},
getters:{// 获取tbsListgetTabs:(state)=>{return state.tabList}},
actions:{},
modules:{}})
功能点:
1:当前活跃的tab就是当前路由的path
2: 页面刷新,tabList数据丢失,则在刷新之前使用sessionStorage进行存储
3:删除tab的时候,活跃的tab变为被删除的前一个或者下一个,删除后重新设置活跃的tab 和tabList
4:监控路由变化,路由变化了,活跃的tab 和tabList 也要随之变化
<template><el-tabs
v-model="activeTab"
closable
@tab-remove="removeTab"
@tab-click="clickBtn"><el-tab-pane:key="index"
v-for="(item, index) in tabList":label="item.title":name="item.path">{{ item.content}}</el-tab-pane></el-tabs></template><script>import storefrom'../../store'exportdefault{
name:'',data(){return{// 当前活跃的tabs
activeTab:'',}},
components:{},
computed:{tabList(){return store.getters['getTabs']},},
watch:{$route:function(){this.setActiveTab()this.addTab()},},created(){},mounted(){this.beforeRefresh()this.setActiveTab()this.addTab()},
methods:{// 设置活跃的tabsetActiveTab(){this.activeTab=this.$route.path},// 添加tabaddTab(){const{ path, meta}=this.$routeconst tab={
path,
title: meta.title,}
store.commit('addTab', tab)},// 点击tabclickBtn(tab){const{ name}= tabthis.$router.push({ path: name})},// 删除tabremoveTab(target){// 当前激活的tablet active=this.activeTabconst tabs=this.tabList// 只有一个标签页的时候不允许删除if(tabs.length===1)returnif(active=== target){
tabs.forEach((tab, index)=>{// 如果删除的就是当前活跃的tab,就把活跃的tab变成上一个或下一个const nextTab= tab[index+1]|| tab[index-1]if(nextTab){
active= nextTab.path}})}// 重新设置当前激活的选项卡和 选项卡列表this.activeTab= active
store.state.tabList= tabs.filter((tab)=> tab.path!== target)},// 解决刷新数据丢失问题beforeRefresh(){
window.addEventListener('beforeunload',()=>{
sessionStorage.setItem('tabsView',JSON.stringify(this.tabList))})let tabSession= sessionStorage.getItem('tabsView')if(tabSession){let oldTabs=JSON.parse(tabSession)if(oldTabs.length>0){
store.state.tabList= oldTabs}}},},}</script>
补充:路由
{
path:'/layout',component:()=>import('../layout/index.vue'),
children:[{
path:'lay1',component:()=>import('../views/lay/Lay1.vue'),
meta:{
title:'选项1'}},{
path:'lay2',component:()=>import('../views/lay/Lay2.vue'),
meta:{
title:'选项2'}},{
path:'lay3',component:()=>import('../views/lay/Lay3.vue'),
meta:{
title:'选项3'}},{
path:'lay4',component:()=>import('../views/lay/Lay4.vue'),
meta:{
title:'选项4'}},}