Vue2+ElementUI实现NavMenu与Tabs联动
使用vue-router、NavMenu(导航菜单)与Tabs(标签页)联动
app.Vue
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
新建布局页与tab页并注册路由
router/index.js :
import Vue from 'vue' import VueRouter from 'vue-router' import layout from '@/views/layout/index.vue' import test1 from '@/views/test1/test1.vue' import test2 from '@/views/test2/test2.vue' const originalPush = VueRouter.prototype.push VueRouter.prototype.push = function push (location) { return originalPush.call(this, location).catch(err => err) } Vue.use(VueRouter) const routes = [ { path:'/', component:layout, children:[ { path:'/test1/test1', name:'test1', component: test1 }, { path:'/test2/test2', name:'test2', component: test2 } ] } ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
views/layout/index.vue :
使用elementUI布局容器,el-container、el-main,并使用el-menu导航菜单和el-tabs标签页;
引入vuex的mapActions,在菜单点击、标签页点击时处理标签列表与当前标签索引
<template>
<div>
<el-container>
<el-aside width="200px">
<!-- :default-active="$route.path" 对应menuItem的index -->
<el-menu mode="vertical" :default-active="$route.path" class="el-menu-vertical-demo">
<el-menu-item
v-for="(item,index) in navList"
:index="item.route"
@click="handClick(item)">{{item.title}}</el-menu-item>
</el-menu>
</el-aside>
<el-main>
<el-tabs v-model="activeName" @tab-click="tabClick">
<el-tab-pane :label="item.title" :name="item.name" v-for="(item, index) in tabsPage"
:key="item.name"></el-tab-pane>
</el-tabs>
<router-view></router-view>
</el-main>
</el-container>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
components: {
},
data() {
return {
navList: [
{ route: '/test1/test1', name: 'test1', title: '测试页面1' },
{ route: '/test2/test2', name: 'test2', title: '测试页面2' }
]
}
},
mounted() {
},
computed: {
activeName: {
get() {
console.log(this.$store.state.curentTab)
return this.$store.state.curentTab
},
set(){}
},
tabsPage: {
get() {
return this.$store.state.tabsPage
}
}
},
methods: {
...mapActions({
handClick: 'editableTabs',
setActiceTab: 'setActiceTab'
}),
tabClick(tab, event) {
let cur = this.tabsPage[tab.index]
this.$router.push({ name: cur.name })
}
},
}
</script>
<style scoped></style>
vuex:store.js处理标签数据和路由跳转
tabs使用的标签数组在vuex中处理,如果数组中没有,添加一个元素并跳转,如果已存在,直接跳转;同时将修改当前标签页索引curentTab,tabs使用
v-model="activeName" 来绑定值,即选中选项卡的 name
import router from '@/router'
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 1,
tabsPage: [],
curentTab: ''
},
getters: {
},
mutations: {
setActiceTab(state, value) {
state.curentTab = value
},
editableTabs: (state, obj) => {
let arr = Array.from(state.tabsPage)
//判断目前tab列表是否已包含该页面
let hasPage = arr.some(item => item.name == obj.name)
if (hasPage) { //如果存在直接跳转
router.push({ name: obj.name })
}
else { //如果没有,添加并跳转
state.tabsPage.push({
name: obj.name,
route: obj.route,
title:obj.title
})
router.push({ name: obj.name })
}
state.curentTab = obj.name
}
},
actions: {
editableTabs(context, obj) {
context.commit('editableTabs', obj);
},
setActiceTab(context,obj){
context.commit('setActiceTab',obj)
}
},
modules: {
}
})
效果:


浙公网安备 33010602011771号