直接上代码!
1.实现tab组件
TabComponent.vue
<template>
<div class="app-wrap">
<!-- 此处放置el-tabs代码 -->
<div class="template-tabs">
<el-tabs
v-model="editableTabsValue"
type="card"
closable
@tab-click="tabClick"
@tab-remove="removeTab">
<el-tab-pane
v-for="(item, index) in editableTabs"
:key="item.name"
:label="item.title"
:name="item.name"
>
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script>
export default {
name: "TabComponent",
data(){
return{
}
},
methods: {
//点击切换tab
tabClick(tab){
let path = tab.name;
this.$store.commit('setTabName', path);
this.$router.push({path: path});
},
//点击移除tab
removeTab(targetName){
if(targetName === "/home"){
return;
}
let tabs;
tabs = typeof this.editableTabs ==='string'? JSON.parse(this.editableTabs):this.editableTabs;
let activeName = this.editableTabsValue;
if (activeName === targetName) {
// 设置当前激活的路由
tabs.forEach((tab,index) =>{
if(tab.name === targetName){
let nextTab = tabs[index +1];
let preTab = tabs[index -1];
if(nextTab){
activeName = nextTab.name;
}else if(preTab){
activeName = preTab.name;
}else {
activeName = "/home";
}
}
});
}
let tab1;
tab1 = tabs.filter(tab => tab.name !== targetName);
this.$store.commit('addTab', tab1);
this.$store.commit('setTabName', activeName);
this.$router.push({path: activeName});
}
},
computed: {
//存放所有tab的数组
editableTabs() {
let tabs;
let data = this.$store.getters.editableTabs;
tabs = typeof data === 'string'? JSON.parse(data):data;
return tabs;
},
//当前tab 初始默认为首页(/home)
editableTabsValue() {
return this.$store.getters.editableTabsValue;
}
},
watch: {
//监听路由的变化来实现添加或切换tab
'$route':function (to) {
let flag = false;
let tabs = this.editableTabs;
let route = this.editableTabsValue;
for (let i = 0;i < tabs.length;i++) {
if (tabs[i].name === to.path) {
flag = true;
//设置当前tab为当前路由
this.$store.commit('setTabName', to.path);
break;
}
}
if (!flag) {
let data = {
title: to.meta.label,
name: to.path,
};
tabs.push(data);
route = to.path;
//设置tab数组
this.$store.commit('addTab', tabs);
this.$store.commit('setTabName', route);
}
}
},
}
</script>
<style scoped>
.template-tabs {
background-color: white;
}
</style>
store文件夹下 index.js
import {Msg} from '../../tools/message/Msg';
import {Auth} from './auth';
export default {
state: {
/** 当前tab '/home' 可以更改为自己默认的页面*/
editableTabsValue:Auth.getEditableTabsValue() || '/home',
/*tab数组*/
editableTabs:Auth.getEditableTabs() || [{title:'首页',name:'/home'}],
},
/** 计算属性 */
getters: {},
/** 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation */
mutations: {
//退出登录时注销tab
ACCOUNT_LOGOUT_FAILURE(state) {
state.editableTabsValue = '/home';
state.editableTabs = [{title:'首页',name:'/home'}];
//其他代码
Auth.removeEditableTabs();
Auth.removeEditableTabsValue()
},
//设置当前tab数组
addTab(state,data){
state.editableTabs = data;
Auth.setEditableTabs(data);
},
//设置当前tab
setTabName(state,data){
state.editableTabsValue = data;
Auth.setEditableTabsValue(data);
}
},
/** Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。 */
actions: {
/** 登出 */
accountLogoutSubmit({commit}, params) {
return new Promise((resolve, reject) => {
UserCountService.logout(params).then((res) => {
commit('ACCOUNT_LOGOUT_FAILURE');
resolve()
}).catch(err => {
commit('ACCOUNT_LOGOUT_FAILURE');
resolve()
})
})
},
}
}
store文件夹下 auth.js
import Cookies from 'js-cookie'
const sessionStorage = window.sessionStorage;
export class Auth {
static getEditableTabs() {
return sessionStorage.getItem('user.editableTabs')
}
static setEditableTabs(value = []) {
return sessionStorage.setItem('user.editableTabs', JSON.stringify(value))
}
static removeEditableTabs() {
return sessionStorage.removeItem('user.editableTabs')
}
static getEditableTabsValue() {
return sessionStorage.getItem('user.editableTabsValue')
}
static setEditableTabsValue(value) {
return sessionStorage.setItem('user.editableTabsValue', value)
}
static removeEditableTabsValue() {
return sessionStorage.removeItem('user.editableTabsValue')
}
}
store文件夹下getter.js
export const getters = {
editableTabsValue:state => state.user.editableTabsValue,
editableTabs:state => state.user.editableTabs,
};
需要使用tab组件的地方
<el-main style="background-color: #F0F0F7">
<div>
<tab-component></tab-component>
<keep-alive>
<div style="background-color: white" >
<router-view/>
</div>
</keep-alive>
</div>
</el-main>