根据不同用户(普通用户,管理员,超级管理员)进行菜单的动态渲染
HTML代码
<el-menu default-active="1" class="el-menu-vertical-demo" :router="true">
<!-- 因为template是虚拟标签所以不能添加key -->
<template v-for="(item, index) in filterMenus">
<el-menu-item v-if="!item.children" :index="item.path" :key="item.id">
<i :class="item.icon"></i>
<span slot="title">{{ item.title }}</span>
</el-menu-item>
<!-- 二级菜单 -->
<el-submenu v-else :index="item.path" :key="index + 1 ">
<!-- 二级菜单标签 -->
<template slot="title">
<i :class="item.icon"></i>
<span>{{ item.title }}</span>
</template>
<el-menu-item
:index="child.path"
v-for="child in item.children"
:key="child.id"
>{{ child.title }}</el-menu-item
>
</el-submenu>
</template>
</el-menu>
其中filterMenus是新创建的菜单,是根据不同的用户创建菜单
JS代码:
data数据
data() {
return {
menus: [
{
id: 1,
title: "首页",
path: "/home",
icon: "el-icon-setting",
// 权限
auth:[0,1,2]
},
{
id: 2,
title: "学生管理",
path: "/home/student",
icon: "el-icon-location",
children: [
{ id: 21,
title: "学生列表",
path: "/home/student",
auth:[0,1]
},
{ id: 22,
title: "学生添加",
path: "/home/addstudent",
auth:[1] },
],
},
{
id: 3,
title: "教师管理",
path: "/home/tacher",
icon: "el-icon-location",
children: [
{
id: 31,
title: "教师列表",
path: "/home/teacher",
auth:[0,1]
},
{
id: 32,
title: "教师添加",
path: "/home/teacheradd",
auth:[1]
},
],
},
{
id: 4,
title: "班级管理",
path: "/home/classes",
icon: "el-icon-location",
children: [
{
id: 41,
title: "班级列表",
path: "/home/classes",
auth:[0,1]
},
{
id: 42,
title: "班级添加",
path: "/home/classesadd",
auth:[1]
},
],
},
{
id:5,
title:'数据管理',
path:'/home/charts',
icon:'el-icon-setting',
auth:[0,1]
}
],
};
},
computed()属性代码
filterMenus(){
//新创建一个菜单
//要返回的菜单
let array = []
//本地获取uerinfo,本地获取不到,返回空对象,因为JSON.parse获取不到会报错
const userInfo = JSON.parse(localStorage.getItem('userInfo')||'{}')
//判断children就是判断二级菜单,但是要判断children的长度,防止children是空的
console.log(userInfo);
this.menus.forEach(item=>{
if(item.children){
if(item.children.length){
//对象解构,创建一个新对象,但是和原来的唯一的区别是children为空
let menu = {...item,children:[]}
console.log('menu',menu);
item.children.forEach(item2=>{
//判断当前用户的角色是否跟菜单匹配
if(item2.auth.includes(userInfo.auth)){
menu.children.push(item2)
}
})
if(menu.children.length){
array.push(menu)
}
}
}else{
//判断一级菜单
if(item.auth.includes(userInfo.auth)){
array.push(item)
}
}
})
console.log(array);
return array
}
使用computed属性的优点:
把数据筛选完可以进行判断
computed属性还可以缓存并且使用直接调用,而mehods需要以函数的方式改变。
权限实现的步骤:
首先先判断登录人的身份,所以要先保存用户的信息userInfo,用户信息里面有识别权限的key(这里是后端提供的), 示例中判断用户的权限是auth
在二级菜单设置auth这个属性,一级菜单不需要添加,因为我们是限制二级菜单里面的选项能不能够被用户选中。在示例中auth是个数组包括0,1,2三个用户。
在示例中JSON.Parse(localStorage.getItem('userInfo' || {}) 添加或,是因为,当我们没有取到userInfo时默认取空对象。
对原数据进行判断,所以用forEach进行遍历,然后再对children进行判断,(有children说明有二级菜单)
如果有children,先对children里面的auth进行判断
如果没有children,则对本身的auth进行判断
例如教师管理:当用户的auth不满足教师管理二级菜单的auth,则不需要给该用户渲染教师管理的二级菜单。
在forEach中进行两次判断
判断是否有children
if(item.children){
children的长度不等于0
if(item.children.length){
先判断一级菜单是否包含二级菜单,当包括二级菜单时,我们就动态新建一个二级菜单
对children进行判断
item.children.forEach(item2=>{
//判断当前用户的角色是否跟菜单匹配,如果匹配则push到menu
if(item2.auth.includes(userInfo.auth)){
menu.children.push(item2)
}
})
最后对一菜单进行判断
//判断一级菜单
if(item.auth.includes(userInfo.auth)){
array.push(item)
}