vue使用el-tabs实现标签页(内存+vuex)
vue使用el-tabs实现标签页(内存+vuex)效果图:1:2:3:内存中这是一个组件,例如:pageTabs.vue(组件是可以做到独立监听路由变化的,所以不需要外部调用什么内部的方法,所以可以抽离成为一个组件),监听路由改变进行新增标签,以及el-tabs组件的切换,删除代码:<template><div class="page-tabs-index"><el
·
vue使用el-tabs实现标签页(内存+vuex)
效果图:
1:
2:
3:内存中
这是一个组件,例如:pageTabs.vue(组件是可以做到独立监听路由变化的,所以不需要外部调用什么内部的方法,所以可以抽离成为一个组件),监听路由改变进行新增标签,以及el-tabs组件的切换,删除
代码:
<template>
<div class="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"
>
<span slot="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) {
// 保存index
let 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));
// 如果删除的是当前的route
if (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 scoped lang="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 3px 0 0;
}
// 左侧第一个
::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>
然后还需要创建一个vuex
export default {
name: 'pageTabs',
state: {
keepAliveList:[],
},
mutations: {
setKeepAliveList (state, list) {
state.keepAliveList = list
}
}
}
然后就去入口页面引入使用即可,例如App.vue
<template>
<div id="app" class="biggbox">
<pageTabs></pageTabs>
<!-- 中部 -->
<transition>
<router-view></router-view>
</transition>
</div>
</template>
还可以用keepAlive
<keep-alive :include="keepAliveList">
<router-view ></router-view>
</keep-alive>
更多推荐
已为社区贡献20条内容
所有评论(0)