菜单权限功能
存在的三个问题
1 不同的账号登录有不同的权限,也就是说,有不同的页面
1.1 首先,在 login.vue页面的登录成功的里面,进行获取到返回数据中携带的页面信息
data.data.menu
1.2 由于信息是许多页面都需要进行使用的,所以进行写在store文件夹下,进行处理
对此,里面包含一个数组menu,和修改的方法 setMenu
export default{
state:{
menu:[]
},
mutations:{
// 用来定义改变state的方法 同步状态
// 此时的state就是接收的上面的
// 设置menu数据
setMenu(state,val){
state.menu = val
}
}
}
1.3 之后便是在登录页面进行调用setMenu,传递参数
// 1 form 表单的校验通过
this.$refs.form.validate((valid) => {
if (valid) {
// 2 如果存在 调用接口 并将form中的数据传入
getMenu(this.form).then(({ data }) => {
// console.log(data);
// 接下来 根据返回的数据code 进行判断是否返回成功
if (data.code === 20000) {
// 表示请求成功,拿到后端返回给我们的token 并保存到 cookie里面
// console.log(data.data.token);
Cookie.set("token", data.data.token);
// 对于左侧列表的显示
// 1 获取数据 存入到 store里面
this.$store.commit("setMenu", data.data.menu);
// 跳转到首页
this.$router.push("/home");
} else {
// 使用的是element-ui 中的 message组件
this.$message.error(data.data.message);
}
});
}
});
},
1.4 将原来写在 components文件夹下的 CommonAside 中的MenuData 数据进行删除,(原来里面的数据时写死的),然后通过在computed计算属性中进行拿到store里面的menu,然后在其他功能进行实现
原来的数据
MenuData: [
{
path: "/",
name: "home",
label: "首页",
icon: "s-home",
url: "Home/Home",
},
{
label: "其他",
icon: "location",
children: [
{
path: "/page1",
name: "page1",
label: "页面1",
icon: "setting",
url: "Other/PageOne",
},
{
path: "/page2",
name: "page2",
label: "页面2",
icon: "setting",
url: "Other/PageTwo",
},
],
},
],
现在的代码:
computed: {
noChildren() {
return this.MenuData.filter((item) => !item.children);
// console.log(arr);
},
hasChildren() {
return this.MenuData.filter((item) => item.children);
},
// 在计算属性里面进行拿到数据
isCollapse() {
return this.$store.state.tab.isCollapse;
},
// 主要的步骤
MenuData() {
// 获取store中的state
return this.$store.state.tab.menu;
},
},
2 由于权限的不同,所以有些页面不能显示,也不能够通过url输入地址的方式进行显示。
例如现在登录的权限存在两种,一种是管理员登录,一种是普通用户进行登录,当管理员进行登录的时候,能够显示所有的页面,而在用户进行登录的时候,只能显示首页和商品管理两项。对于用户来说,不能够通过url跳转到user也就是用户管理页面。
具体的功能:
类似于数据间的通信,也需要在state里面定义一个方法,用来接收登录传来的url数据。
在login.vue页面中,在其中的methods方法中进行写:
获取当前的路由,传到设置的方法中
在store文件夹下的tab.js文件中:
// 动态进行路由的修改 动态注册路由
// 在登录的时候进行调用
addMenu(state,router){
// 判断 当前缓存中是否有数据
if(!Cookie.get('menu')) return
const menu = JSON.parse(Cookie.get('menu'))
state.menu = menu
// 组装动态路由数据的处理
const menuArray = []
menu.forEach(item =>{
// 判断是否存在子菜单
if(item.children){
item.children = item.children.map(item=>{
item.component = () => import(`../views/${item.url}`)
return item
})
menuArray.push(...item.children)
}else{
// 没有子菜单
// component:()=>import('../views/home')
item.component = () => import(`../views/${item.url}`)
menuArray.push(item)
}
})
console.log( menuArray,' menuArray');
//路由的动态添加
menuArray.forEach(item =>{
// 动态添加路由
router.addRoute('Main',item)
})
}
3 对于菜单的数据在不同页面之间的数据通信
注意: 此时第一点存在一个问题,就是当页面进行刷新的时候,左侧的菜单栏会没有,其实是因为 数据存在于 store.state 里面,而state存在于 浏览器的内存中,所以浏览器一刷新,导致state里面的数据就不存在了,所以要进行一下缓存,叫做数据的持久化,通过cookie进行缓存。
解决代码
store中的
// 设置menu数据
setMenu(state,val){
state.menu = val
// stringify将一个对象 序列化成字符串
Cookie.set('menu',JSON.stringify(val))
}
CommonAside
MenuData() {
// 获取store中的state
// JSON.parse将原来的数据还原
// 判断当前数据,缓存中没有,从当前store中获取,
// 缓存中有 从cookie进行获取
return JSON.parse(Cookie.get("menu")) || this.$store.state.tab.menu;
},