效果图
![bfa6528395b88dda8202666484a6a44f.png](https://img-blog.csdnimg.cn/img_convert/bfa6528395b88dda8202666484a6a44f.png)
- 创建router
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: Home,
children: [
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
},
{
path: '/index',
name: 'index',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/Index.vue')
},
{
path: '/index01',
name: 'index01',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/Index01.vue')
},
{
path: '/index02',
name: 'index02',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/Index02.vue')
},
{
path: '/index03',
name: 'index03',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/Index03.vue')
},
],
},
]
const router = new VueRouter({
routes
})
export default router
- 创建store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
currentTab:'/',//默认定位到首页
tabList:[
],
},
mutations: {
updateCurrentTabState(state, current){
state.currentTab = current
},
updateTabListState(state, current){
let tabs = state.tabList;
let tab = tabs.find(info=>info.href===current.href);
if (!tab){
tabs.push(current);
state.tabList = tabs;
}
},
removeCurrentTabState(state, href){
let tabs = state.tabList;
tabs.forEach((item,index)=>{
if (item.href === href){
tabs.splice(index,1);
if (state.currentTab === item.href){
let newIndex = index-1;
if (newIndex>=0){
let newTab = tabs[index-1];
state.currentTab = newTab.href;
}
}
}
})
state.tabList = tabs;
}
},
actions: {
},
modules: {
}
})
- 实现tab切换逻辑
<template>
<el-container style="border: 1px solid #eee">
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<el-menu>
<el-submenu index="1">
<template slot="title"><i class="el-icon-message"></i>多tab测试</template>
<el-menu-item @click="to('about')" index="1-1">about</el-menu-item>
<el-menu-item @click="to('index')" index="1-2">index</el-menu-item>
<el-menu-item @click="to('index01')" index="1-3">index01</el-menu-item>
<el-menu-item @click="to('index02')" index="1-4">index02</el-menu-item>
<el-menu-item @click="to('index03')" index="1-5">index03</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-tabs v-model="currentTab" type="card" editable @edit="handleTabsEdit" @tab-click="clickTo">
<el-tab-pane
v-for="(item, index) in list"
:key="index"
:label="item.label"
:name="item.href"
>
</el-tab-pane>
</el-tabs>
<el-main>
<keep-alive :include="includeList" :max="100">
<router-view />
</keep-alive>
</el-main>
</el-container>
</el-container>
</template>
<style>
.el-header {
background-color: #e0e0e0;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
<script>
export default {
data() {
const item = {
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
};
return {
tableData: Array(20).fill(item)
}
},
methods:{
to (name) {
let item = {href:'/'+name,label:name}
if (item.href !== this.currentTab) {
this.$store.commit('updateTabListState', item)
this.$store.commit('updateCurrentTabState', item.href)
}
},
clickTo (tab) {
let item = {href:tab.name,label:tab.label}
if (item.href !== this.currentTab) {
this.$store.commit('updateTabListState', item)
this.$store.commit('updateCurrentTabState', item.href)
}
},
remove (href) {
this.$store.commit('removeCurrentTabState', href)
},
handleTabsEdit(targetName, action) {
if (action === 'remove') {
this.remove(targetName)
}
}
},
watch: {
currentTab (value) {
console.log(value)
this.$router.push({ path: value })
}
},
computed: {
includeList(){
let list = this.$store.state.tabList.map(item=>{
return item.name
})
return list
},
list () {
return this.$store.state.tabList
},
currentTab: {
get () {
return this.$store.state.currentTab
},
set () {
}
}
},
};
</script>
- 实现页面的缓存和释放
<keep-alive :include="includeList" :max="100">
<router-view />
</keep-alive>