思路:
1、点击左侧菜单栏:菜单栏高亮、tab标签增加并高亮、session增加一项、路由和对应内容跳转
2、点击tab标签:其高亮、路由和对应内容跳转
3、点击删除tab标签:session里删除,
①若删除的是中间项,高亮为删除前一项;
②若删除的是最后一项,高亮为其前一项;
③若删除的是第一项,高亮为其后一项;
路由和对应内容跳转
4、退出登录:session里清空、重置tab数组为空
一、点击菜单栏,这里只写了点击菜单事件
// 点击菜单
clickMenu(item) {
// console.log(item)
// sessionStorage.setItem('menu',JSON.stringify([]))
let arr = JSON.parse(sessionStorage.getItem('menu')) || []
console.log(Array.isArray(arr))
// 当页面的路由与跳转的路由不一致才允许跳转
if (this.$route.path !== item.path && !(this.$route.path === '/login' && (item.path === '/login'))) {
this.$router.replace({ path: item.path }).catch(err => console.log(err))
}
this.$store.commit('addTab', item)
const isExist = arr.some(i => i.name === item.name)
// 如果不存在添加
if (!isExist) {
arr.push(item)
}
window.sessionStorage.setItem('menu',JSON.stringify(arr))
}
二、标签栏 ,标签组件单拿出来了 commoTag.vue
<template>
<div class="tabs">
<el-tabs type="card"
:value="$route.path"
@tab-click="tabClick"
closable
class="my-tabs"
@edit="handleTabsEdit">
<el-tab-pane :key="item.path"
v-for="(item) in tabsValue"
:label="item.label"
:name="item.path">
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
name: 'CommonTag',
data() {
return {}
},
computed: {
...mapState({
tabsValue: state => state.tab.tabsList
})
},
methods: {
...mapMutations(['closeTag']),
// 路由跳转
tabClick ({ name }) {
if (name === this.$route.path) return
this.$router.push(name)
},
// 删除选项卡
handleTabsEdit (targetPath, action) {
if (action === 'remove') {
if (targetPath === '/home') return
let nextTab = {}
// 找到下一个路由
this.tabsValue.forEach((item, index) => {
if (item.path === targetPath) {
nextTab = this.tabsValue[index + 1] || this.tabsValue[index - 1]
}
})
this.$store.commit('removeTab', targetPath)
// 如果删除的是当前页,则进行跳转
targetPath === this.$route.path && this.$router.push(nextTab.path)
// 过滤掉session
let arr = JSON.parse(sessionStorage.getItem('menu'))
let arr1 = arr.filter(i => i.path !== targetPath)
sessionStorage.setItem('menu',JSON.stringify(arr1))
}
}
},
}
</script>
<style lang="less" scoped>
.tabs {
float: left;
.el-tag {
margin-right: 10px;
cursor: pointer;
}
}
</style>
三、新建store文件夹,和components同级
store/tab.js
export default {
state: {
tabsList: JSON.parse(sessionStorage.getItem('menu')) ||[]
},
mutations: {
// 菜单栏点击,添加tab
addTab: (state, val) => {
// 如果tab已经存在,不添加新的tabs
if (state.tabsList.some(item => item.path === val.path)) return
state.tabsList.push(val)
},
// 删除指定的tab
removeTab(state, targetPath) {
state.tabsList = state.tabsList.filter(item => item.path !== targetPath)
},
// 初始化数据,在注销时调用
resetTab(state) {
state.tabsList = []
}
}
}
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import tab from './tab'
Vue.use(Vuex);
//创建vuex的实例
export default new Vuex.Store({
modules:{tab}
})
在main.js里实例化
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import '../src/assets/css/global.css'
import { instance } from './request/axios';
import VueRouter from 'vue-router'
import store from './store';
Vue.use(ElementUI);
Vue.use(VueRouter)
new Vue({
router,
render: h => h(App),
store
}).$mount('#app')
四、退出登录时,清空session,重置resetTab
exitLogin() {
sessionStorage.removeItem('menu')
this.$store.commit('resetTab');
this.$router.push('/login')
},