思想:请求导航菜单数据和帐号信息数据后,存到vuex中,方便后期使用。
如何根据账号权限动态渲染导航菜单?
请求到当前帐号信息后,在导航渲染区域加上如下代码。此时,导航已被请求到的menuList所渲染完毕。若此账号的权限不包含此项菜单的路径,则disabled掉(permissions为数组,每一项是此账号被授权的路径):
<el-menu-item :disabled="accountInfo.permissions.indexOf(children.path) === -1" >
home.vue组件部分代码:
<!-- -->
<template>
<div>
<el-container>
<!-- 导航 -->
<el-aside style="width: auto">
<el-menu
default-active="1-4-1"
class="el-menu-vertical-demo"
:collapse="isCollapse"
:collapse-transition="false"
v-if="menuList && accountInfo"
>
<!-- 以防ajax没请求回来,下面若用到menuList,accountInfo会报undefined错 -->
<el-menu-item>
<i class="el-icon-location"></i>
<span slot="title">首页</span>
</el-menu-item>
<el-submenu
v-for="item in menuList"
:key="item.uid"
:index="item.path"
>
<!-- 一级菜单模版区域 -->
<template slot="title">
<i :class="iconsObj[item.id]"></i>
<span slot="title">{{ item.name }}{{ item.path }}</span>
</template>
<el-menu-item
v-for="children in item.children"
:key="children.uid"
:index="children.path"
:disabled="accountInfo.permissions.indexOf(children.path) === -1"
>
<!-- 二级菜单模版区域 -->
<template slot="title">
<i :class="iconsObj[children.id]"></i>
<span slot="title">{{ children.name }}{{ children.path }}</span>
</template>
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<!-- 右侧 -->
<!-- 以防ajax没请求回来,下面若用到accountInfo会报undefined错 -->
<el-main v-if="accountInfo">
<div style="height: 50px; line-height: 50px; background: #ccc">
<el-row>
<el-col :span="12">
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
<el-radio-button :label="false">展开</el-radio-button>
<el-radio-button :label="true">收起</el-radio-button>
</el-radio-group>
</el-col>
<el-col :span="12">
<div style="text-align: right; padding-right: 40px">
当前用户:
<router-link to="/info" style="color: deepskyblue">
{{ accountInfo.profile.name }}
</router-link>
</div>
</el-col>
</el-row>
</div>
<div>
<router-view></router-view>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
import api from "../../utils/api/home";
import { mapState } from "vuex";
export default {
name: "",
data() {
return {
isCollapse: false,
iconsObj: {
1: "el-icon-setting",
2: "el-icon-tickets",
4: "el-icon-user",
12: "el-icon-s-custom",
21: "el-icon-s-check",
17: "el-icon-menu",
22: "el-icon-collection",
41: "el-icon-s-order",
46: "el-icon-document-add",
42: "el-icon-document",
45: "el-icon-folder-opened",
},
};
},
computed: {
//state
...mapState({
menuList: (state) => state.menu.menuList,
accountInfo: (state) => state.user.accountInfo,
})
},
created() {},
mounted() {
this.getMenu();
this.getAccountInfo();
},
methods: {
//获取导航菜单数据
getMenu() {
api
.getMenuList()
.then((res) => {
//修改导航状态树
this.$store.commit("setMenu", res.data);
})
.catch((err) => {
console.log(err);
});
},
//获取当前帐号信息
getAccountInfo() {
api
.getAccountInfo()
.then((res) => {
//修改帐号状态树
this.$store.commit("setInfo", res.data);
console.log(res);
})
.catch((err) => {
console.log(err);
});
},
},
};
</script>
<style scoped>
</style>
main.js:
import Vue from 'vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue'
import router from './router/index'
import store from './store/index'
//全局使用
Vue.use(ElementUI);
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
store > index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import menu from './modules/menu'
import user from './modules/user'
export default new Vuex.Store({
modules: {
menu,user
}
})
// export default new Vuex.Store({
// state,//数据
// getters,//计算属性,可以重新计算state,用法相当于computed
// mutations,//同步函数 要想改变state,得在组件的方法中调用mutations的方法,具体操作写在mutations中
// actions,//提交mutations——可以包括异步如setTimeout一个mutation方法,也可以在里面写条件判断决定提交哪个mutations,不能直接变更state
// })
store > modules > menu.js
export default {
//局部
state: {
menuList: []
},
//全局
mutations: {
//修改导航菜单数据
setMenu(state, data) {
//console.log(this.state);//若想调取其它modules下js的state
state.menuList = data
}
}
}
store > modules > user.js
export default {
state: {
accountInfo: ''
},
mutations: {
//修改当前帐号信息
setInfo(state, data) {
state.accountInfo = data
}
}
}