vuex实现菜单栏与标签页联动效果
vuex简介
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
项目场景
vue-cli + Element-UI 框架 前端页面
左侧菜单栏
步骤:
1)需要注意使用router进行跳转,与标签页联动也是由于router发生了跳转而新建标签页。
<el-submenu :index="menu.pCode" v-for="menu in menuList" :key="menu.pId">
<template slot="title">
<i :class="menu.pIcon"></i>
<span>{{menu.pName}}
</span>
</template>
<!-- 二级菜单 有子菜单-->
<template v-for="cMenu in menu.children">
<el-submenu :index="cMenu.pCode" v-if="cMenu.children" :key="cMenu.pId">
<template slot="title">{{cMenu.pName}}</template>
<!-- 三级菜单 -->
<template v-for="gMenu in cMenu.children">
<el-menu-item :index="gMenu.pCode" :key="gMenu.pId">
{{gMenu.pName}}
</el-menu-item>
</template>
</el-submenu>
<!-- 二级菜单 没有子菜单-->
<el-menu-item :index="cMenu.pCode" v-if="!cMenu.children" :key="cMenu.pId">{{cMenu.pName}}</el-menu-item>
</template>
</el-submenu>
</el-menu>
</el-aside>
data() {
return{
//权限控制,数据库中查出当前登录人权限
menuList: [],
}
}
2)引入vuex模块
npm install --save vuex
import store from ‘./store/store.js’
在Vue中注册
new Vue({
el: '#app',
components: { App },
template: '<App/>',
router,
store,
})
在src目录下新建store/store.js文件,代码如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
//存储标签页数组
openTab: [],
//当前展开的标签页
activeIndex: ''
},
mutations: {
add_tabs (state, data) {
//屏蔽某些不需要打开标签页的路由
if(data.name!="routerName1" && data.name!="routerName2"){
this.state.openTab.push(data);
}
},
//关闭时删除
delete_tabs (state, route) {
let index = 0
for (let item of state.openTab) {
if (item.route === route) {
break
}
index++
}
this.state.openTab.splice(index, 1)
},
//设置当前选中的标签页
set_active_index (state, index) {
this.state.activeIndex = index
},
//登录失效 或者 退出登录后, 清空标签页
clear_tabs (){
this.state.openTab.length = 0;
}
}
})
标签页
基于Element-UI中的标签页组件样式
<el-tabs v-model="activeIndex" type="card" closable @tab-click="clickTab" @tab-remove="removeTab">
<el-tab-pane
:key="item.name"
v-for="item in openTab"
:label="item.name"
:name="item.route"
>
</el-tab-pane>
</el-tabs>
<!-- 路由显示出口 -->
<router-view/>
标签页组件函数
//点击时,路由跳转
clickTab (tab) {
this.$router.push({path: this.activeIndex})
},
//关闭标签页
removeTab (target) {
//首页不能关闭
if(target === "/home/index"){
return;
}
this.$store.commit('delete_tabs', target)
//判断关闭页是否是当前点开的标签页
if (this.activeIndex === target) {
// 设置当前激活的路由
if (this.openTab && this.openTab.length > 1) {
this.$store.commit('set_active_index',
this.openTab[this.openTab.length - 1].route)
this.$router.push({path: this.activeIndex})
} else {
this.$router.push("/home/index");
}
}
}
route.js
注:路由 name 为标签页文本名
如: { path: “/home/index”, name: “首页”, component: Index }
总结
经验:参考了一些博客,看了vuex文档后,实现了这个效果该有的基本功能,遇到没使用过的技术不要着急,耐下心来看下文档很有帮助。
可提升点:页面刷新后,标签页会只保留主页。