【Vue2+Element ui通用后台】菜单权限

文章目录

  • 不同账号不同菜单
  • 动态注册路由
  • 资源下载

对于菜单权限我们需要解决以下问题:
1、不同的账号登录,有不同的菜单
2、通过输入url地址来显示页面,所以应该根据权限动态注册路由
3、对于菜单数据,在不同页面之间的数据通信

不同账号不同菜单

现在项目中的菜单,我们是在 CommenAside 中写死的,现在我们需要根据登录后返回的权限动态展示,所以我们找到登录后的代码,修改 Login.vue,在 submit 方法登录成功后,将菜单数据存入 store 中

submit(){
      //校验通过
      this.$refs.form.validate((valid)=>{
        if(valid){
          getMenu(this.form).then(({data})=>{
            // console.log('TTT',data);
            if(data.code === 20000){
              // token信息存入cookie用于不同页面间的通讯
              Cookie.set('token',data.data.token);
              // 获取菜单数据,存入store
              this.$store.commit('setMenu',data.data.menu);
              // 跳转首页
              this.$router.push('home')
            } else {
              this.$message.error('账号信息错误');
            }
          })
        }
      })
    }

修改 tab.js

import {findIndex} from "core-js/internals/array-iteration";

export default {
    state:{
        ......
        menu:[]
    },
    mutations:{
        ......
        // 设置菜单
        setMenu(state,val){
            state.menu = val
        }
    }
}

然后修改 CommonAside 中的代码,我们定义一个计算属性 menuData,通过 store 中存入的 menu 获取,所以 data 中的 menuData 可以删掉了

<script>
export default {
  data() {
    return {};
  },
  ......
  computed:{
    ......
    menuData(){
      return this.$store.state.tab.menu;
    }
  }
}
</script>

登录成功后可以看到左侧菜单是展示的
【Vue2+Element ui通用后台】菜单权限_第1张图片
但是现在存在一个问题,刷新后菜单就消失了
【Vue2+Element ui通用后台】菜单权限_第2张图片
因为 store 中的 state 数据是存在浏览器的内存中的,所以刷新后就不存在了,所以如果需要持久化,就需要缓存

因为 Cookie 的数据必须是字符串,所以需要序列化字符串,所以修改 tab.js 中 setMenu 方法

setMenu(state,val){
	state.menu = val;
	Cookie.set('menu',JSON.stringify(val))
}

修改 CommonAside.vue 中获取菜单的方法

menuData(){
      return JSON.parse(Cookie.get('menu')) || this.$store.state.tab.menu;
}

这样登录账号后,再刷新就不会有问题了
账号:admin
密码:admin

动态注册路由

现在来解决第二个问题,如果我们登录另一个账号
账号:xiaoxiao
密码:xiaoxiao

可以看到左侧只有两个菜单了。但是有个问题是,如果我们在浏览器输入 /user 的链接,还是可以打开用户列表的页面
【Vue2+Element ui通用后台】菜单权限_第3张图片
原因就是在 router/index.js 中我们是写死的这些路径
【Vue2+Element ui通用后台】菜单权限_第4张图片
我们需要动态注册路由,在 tabs.js 中增加动态添加相应方法:

// 动态注册路由
        addMenu(state,router){
			
        }

在 Login.vue 中,当存入菜单后,调用 addMenu

// 获取菜单数据,存入store
this.$store.commit('setMenu',data.data.menu);
this.$store.commit('addMenu',this.$router);

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 {
                    // 没有子菜单
                    item.component = ()=> import(`../views/${item.url}`)
                    menuArray.push(item)
                }
            })
            // console.log('menuArray',menuArray);
            //路由的动态添加
            menuArray.forEach(item=>{
               router.addRoute('Main',item);
            })
        }

我们看下打印结果:
【Vue2+Element ui通用后台】菜单权限_第5张图片
【Vue2+Element ui通用后台】菜单权限_第6张图片
由于上边动态添加路由时:router.addRoute('Main'); 使用的是 name 属性,所以修改 index.js,给主路由增加 name 属性
【Vue2+Element ui通用后台】菜单权限_第7张图片
最后,找到登出位置 CommonHeader.vue,在登出的时候清空 Cookie中的menu数据

handleCommand(command){
      if(command === 'cancel'){
        .....
        // 清除Cookie中的menu数据
        Cookie.remove('menu');
        ......
      }
    }

最后在 index.js 中注释掉写死的路由数据

【Vue2+Element ui通用后台】菜单权限_第8张图片

下面进行测试,首先登录 admin/admin,可以看到显示了全部的菜单
【Vue2+Element ui通用后台】菜单权限_第9张图片
退出,然后登录 xiaoxiao/xiaoxiao,可以看到只有首页和商品管理两个菜单
【Vue2+Element ui通用后台】菜单权限_第10张图片
再次输入 /user 可以看到访问不到了
【Vue2+Element ui通用后台】菜单权限_第11张图片
现在有一个问题就是刷新以后页面是空白的,原因就是登录以后调用了 addMenu,刷新后整个 vue 实例已经初始化了,就不会走这个方法了,我们需要在 main.js 中修改初始化 vue 实例,在 created 时再次走 addMenu 方法

new Vue({
    router,
    store,
    render: h => h(App),
    created() {
        store.commit('addMenu',router)
    }
}).$mount('#app')

资源下载

资源下载

你可能感兴趣的:(Vue学习笔记,elementui,vue)