标签页放在main中 标签页el-tabs主要属性: (1)editableTabsValue:高亮表示被选中的标签页(通过name标识) (2)editableTabs:标签页数组(存储所有的标签页信息),属性:name、title
<!-- 标签页-->
<el-tabs v-model="editableTabsValue" type="card" closable @tab-remove="removeTab" @tab-click="selectTab">
<el-tab-pane
v-for="(item, index) in editableTabs"
:key="item.name"
:label="item.title"
:name="item.name"
>
</el-tab-pane>
</el-tabs>
editableTabsValue、editableTabs存放在store中
1、点击菜单项生成新的标签页
点击菜单项生成新的标签页,添加新的标签页前要判断标签页数组中是否已经包含该标签页,如果已经拥有该标签页,只需要选中该标签页。 示例: 通过点击事件addTabs将菜单项的title和name添加到标签页数组中
<el-menu-item index="/index" @click="addTabs({title:'首页',name:'/index'})">
<i class="el-icon-s-home"></i>
<span slot="title">首页</span>
</el-menu-item>
<el-menu-item :index="item.name" :route="{path:item.path}" v-for="item in menu.children" @click="addTabs(item)">
<template slot="title">
<i :class="item.icon"></i>
<span>{{item.title}}</span>
</template>
</el-menu-item>
store中对应的addTabs方法,添加一个新标签项同时将其置为高亮,即选中状态。
addTab(state,item){
let index = state.editableTabs.findIndex(e => e.name===item.name)
if(index===-1){
state.editableTabs.push({
title: item.title,
name: item.name
})
}
state.editableTabsValue = item.name
}
因为标签页数组editableTabs是动态更新的,所以在main中要动态获取editableTabsValue 、editableTabs值。通过computed实现。 如下:
computed:{
editableTabsValue: {
get(){
return this.$store.state.menus.editableTabsValue;
},
set(val){
this.$store.state.menus.editableTabsValue = val;
}
},
editableTabs:{
get(){
return this.$store.state.menus.editableTabs;
},
set(val){
this.$store.state.menus.editableTabs = val;
}
}
},
2、点击标签页项实现页面跳转
在标签页中添加绑定事件@tab-click=“selectTab” 标签页部分
<el-tabs v-model="editableTabsValue" type="card" closable @tab-remove="removeTab" @tab-click="selectTab">
<el-tab-pane
v-for="(item, index) in editableTabs"
:key="item.name"
:label="item.title"
:name="item.name"
>
通过路由跳转函数selectTab实现页面跳转。 前提,菜单项的name要和路由项的name相同
selectTab(target){
this.$router.push({name:target.name}).catch(err => {
console.log(err)
})
}
router.push()参数详解
3、bug
bug1: 当刷新页面时,之前显示的标签页都消失了。 原因:vuex store中的数据会随着页面刷新恢复默认。 解决方法:将editableTabs、editableTabsValue存放在session中。 在页面刷新时将vuex里面的信息保存在sessionStorage,页面加载时读取session中的信息,并加载到store中。 在App.vue中操作
created() {
window.addEventListener("beforeunload",() => {
sessionStorage.setItem("editableTabs",JSON.stringify(this.$store.state.menus.editableTabs))
sessionStorage.setItem("editableTabsValue",this.$store.state.menus.editableTabsValue)
})
sessionStorage.getItem("editableTabsValue")&&this.$store.commit("getEditableTabsValue",sessionStorage.getItem("editableTabsValue"))
sessionStorage.getItem("editableTabs")&&this.$store.commit("getEditableTabs",JSON.parse(sessionStorage.getItem("editableTabs")))
},
对应store中的相关函数,getEditableTabsValue、getEditableTabs
getEditableTabsValue(state,editableTabsValue){
state.editableTabsValue = editableTabsValue
},
getEditableTabs(state,editableTabs){
state.editableTabs = editableTabs
},
bug2: 如果直接通过url访问某个菜单项,此时store和session中都没有相关标签页信息,那么此时标签页会显示空白。所以在App.vue中增加一个监听watch
watch: {
$route(to,from){
if(to.path !== '/login'){
let obj = {
title: to.meta.title,
name: to.name
}
this.$store.commit("addTab",obj)
}
}
}
注意:此处使用的时route。 route和router区别 bug3: 用户退出后,store的信息没有恢复默认
logout(){
this.$axios.post('/logout').then(res => {
localStorage.clear()
sessionStorage.clear()
this.$store.commit("resetState");
this.$store.commit("resetEditableTabs")
this.$store.commit("resetEditableTabsValue")
router.push('/login')
})
},
|