vue使用el-tabs实现标签页(内存+vuex)
效果图:
1:
2:
3:内存中
<template><divclass="page-tabs-index"><el-tabs v-model="activeRoute"type="card" :closable="closable" @tab-click="clickTab" @edit="handleTabsEdit"><el-tab-pane :key="index" v-for="(item, index) in tabs" :label="item.title" :name="item.route"><spanslot="label" @click.middle="removeTabByMiddle(item.route)">{{item.title}}</span></el-tab-pane></el-tabs></div></template><script>export default{data(){ return{ closable: false, activeRoute:'', tabs:[]}}, methods:{ // 增删tabs handleTabsEdit(targetName,action){ // console.log('tab增删:',targetName,action); if(action==='remove'){ this.methods('removeTab',targetName); this.methods('checkClosable');}}, // 鼠标中键删除 removeTabByMiddle(route){ if(this.closable){ this.methods('removeTab',route); this.methods('checkClosable');}}, // 点击tab,item是被选中的标签的vue实例 clickTab(item){ if(this.$route.name=== item.name){return;} // console.log('tab切换:', item.name); this.$router.push({name:item.name})}, // 这里需要配合keep-alive的includeAPI,设置vuex的缓存list,以实现tab关闭后vue不缓存该页面 // 加载tabs缓存loadTabs(){ const pageTabs= sessionStorage.getItem('page-tabs');if(pageTabs){ this.tabs= JSON.parse(pageTabs);} this.$store.commit('setKeepAliveList',this.tabs.map(i=>i.route));}, // tab切换更新updateTabs(){ const route= this.$route.name; const title= route; if(!route|| route==='index'){ // 这里是处理layout中第一次加载会是null,后续由监听$route更新,(index路由是引导用的,不需要) // 而如果是当从没有tabs的页面跳转过来时,不走下面,将不会变更当前激活return;} // 新增if(!this.tabs.find(i=> i.route=== route)){ this.tabs.push({ route, title});} this.activeRoute= route; // this.$route.meta.keepAlive=true; // 缓存tabs sessionStorage.setItem('page-tabs', JSON.stringify(this.tabs)); this.$store.commit('setKeepAliveList',this.tabs.map(i=>i.route));}, // 移除tab removeTab(route){ // 保存indexlet index= this.tabs.findIndex(i=> i.route=== route); this.tabs= this.tabs.filter(i=> i.route!== route); this.$store.commit('setKeepAliveList',this.tabs.map(i=>i.route)); // 如果删除的是当前的routeif(this.activeRoute=== route){ // 将当前激活route切换为刚才删除的后一个if(index> this.tabs.length-1){ index -=1;} this.activeRoute= this.tabs[index].route; // this.$route.meta.keepAlive=false; this.$router.push({ name: this.activeRoute});} // 缓存tabs sessionStorage.setItem('page-tabs', JSON.stringify(this.tabs));}, // 检查是否可以继续删除checkClosable(){ this.closable= this.tabs.length>1;}},created(){ // this.lists= this.$store.state.other.houseList;},mounted(){ this.loadTabs() this.updateTabs() this.checkClosable()}, watch:{ $route(){ this.loadTabs() this.updateTabs() this.checkClosable()}}}</script><style scopedlang="scss"> // 组件高度$tabLineHeight:30px; // 边框颜色$borderColor:#488ba0; // 未激活的以及tab本身的背景$background:#09142e; // 激活的标签的背景$background-active:#488ba0; // 未激活标签的字体颜色$fontColor:#30c0cd; .page-tabs-index{ height:$tabLineHeight; ::v-deep .el-tabs{} // 底部横线 ::v-deep .el-tabs__header{ height:$tabLineHeight; background:$background; box-sizing: border-box; border-bottom: 1px solid$borderColor;} // 左右滚动按钮 ::v-deep .el-tabs__nav-prev{ height:$tabLineHeight; line-height:$tabLineHeight;} ::v-deep .el-tabs__nav-next{ height:$tabLineHeight; line-height:$tabLineHeight;} ::v-deep .el-tabs__nav{ border-radius:0; border-left: none; border-right: none; border-top: none;} ::v-deep .el-tabs__item{ height:$tabLineHeight; line-height:$tabLineHeight; border-color:$borderColor; color:#fff; border-right: 1px solid$borderColor; //border-radius: 3px 3px00;} // 左侧第一个 ::v-deep .el-tabs__item.is-active:first-child{ border-left: none;} ::v-deep .el-tabs__item:not(.is-disabled){ color:$fontColor; border-left: none; border-top: 2px solid transparent;} ::v-deep .el-tabs__item.is-active{ border-bottom: 1px solid$background-active; border-top: 2px solid$borderColor; border-right: 1px solid$borderColor; background:$background-active; color:#fff;}}</style>
export default{ name:'pageTabs', state:{ keepAliveList:[],}, mutations:{ setKeepAliveList(state, list){ state.keepAliveList= list}}}
<template><divid="app"class="biggbox"><pageTabs></pageTabs><!-- 中部 --><transition><router-view></router-view></transition></div></template>
<keep-alive :include="keepAliveList"><router-view></router-view></keep-alive>