zoukankan      html  css  js  c++  java
  • Vue动态菜单(路由)的实现方案(beforeEach+addRoutes+elementUI)

    前言

    我之前总结过动态菜单的实现方案>动态菜单实现,
    只不过这篇写的有点稍微复杂,是用后端返回当前登录角色的路由表实现的,也就是前端只要从后端取到路由表进行渲染菜单即可;

    今天,我再讲解一种方案:路由表写在前端,后端返回用户的角色,前端进行角色对应的菜单渲染

    在线预览:动态路由
    github(记的star哈):https://github.com/Mrblackant...
    图片描述

    开始之前,自己要大概懂写关于vue-router的beforeEach(路由拦截)、addRoutes,elementUI的菜单组件等方法,不然理解可能会有点吃力

    思路

    分以下几步:
    1.前端在本地写好路由表,以及每个路由对应的角色,也就是哪些角色可以看到这个菜单/路由;
    2.登录的时候,向后端请求得到登录用户的角色(管理者、普通用户);
    3.利用路由拦截,根据取到的用户角色,跟本地的路由表进行对比,过滤出用户对应的路由,并利用路由进行左侧菜单渲染

    实现

    根据上述的3步,我们进行每一步的实现

    1.前端本地写好路由表
    我们分成两个路由表,一个是固定的,比如首页展示,每个人都能看到,一个需要根据用户角色动态展示的;
    这里就利用到了router的meta属性,我们在这里边写上菜单对应的:icon,对应的哪些角色可以看到这个菜单:roles
    一个完整的路由表如下:

    //代码位置:router/index.js
     {
        path: '',
        component: layout, //整体页面的布局(包含左侧菜单跟主内容区域)
        children: [{
          path: 'main',
          component: main,
          meta: {
            title: '首页', //菜单名称
            roles: ['user', 'admin'], //当前菜单哪些角色可以看到
            icon: 'el-icon-info' //菜单左侧的icon图标
          }
        }]
      }

    2.用户登录,取到用户的角色
    本来我是写了mock数据,模拟用户登录,请求后端角色的接口,奈何mock挂了,
    所以我就直接模拟了:

    取到用户角色,存放进localStorage,然后跳转主页

    //代码位置:src/components/reLoad.vue
    
      // axios.post('/temp',this.formModel).then(res=>{})      
          // 我暂时就不模拟了,直接取
          let getUserRole = this.formModel.user === 'admin' ? 'admin' : 'user'
          localStorage.setItem('userRole', getUserRole)
          this.$router.push({
            path: '/main'
          })

    3.路由拦截beforeEach,并过滤出角色对应的路由表

    经过第2步,我们已经得到了用户的角色,这时候在路由拦截的地方我们就可以取到了,

    取到之后,结合第1步我们写好的路由,利用数组的filter方法,拿角色跟路由表里meta标签里的roless数据进行对比

    过滤好了,拿当前路由去渲染左侧菜单,这一步其实可以用vuex去实现,我担心有的小伙伴不理解,就用一个global(全局变量)替代了

    尤其要注意路由拦截这里,很容易陷入死循环,所以我建议大家先了解一下beforeEach和addRoutes的运行机制

    //代码位置:src/permission.js
    
    router.beforeEach((to, from, next) => {
      // 取到用户的角色
      let GetRole = localStorage.getItem("userRole")
    
      // 如果登录了
      if (GetRole !== 'unload') {
        next() //next()方法后的代码也会执行
        // 1.如果路由表 没根据角色进行筛选,就筛选一次
        if (!addRouFlag) {
          addRouFlag = true
          // 2.根据用户的角色、和需要动态展示的路由,生成符合用户角色的路由
          var getRoutes = baseRoleGetRouters(permissionRouter, GetRole.split(","))
          // 3.利用global属性,让渲染菜单的组件sideMeuns.vue重新生成左侧菜单
          global.antRouter = fixedRouter.concat(getRoutes)
          // 4.将生成好的路由addRoutes
          router.addRoutes(fixedRouter.concat(getRoutes))
          // 5.push之后,会重新进入到beforeEach的钩子里,直接进入第一个if判断
          router.push({ path: to.path })
        }
      } else {
        // 用户没登录,跳转到登录页面
        if (to.path === '/') {
          next()
        } else {
          next('/')
        }
      }
    
    })

    整体流程走完了,再容易让人蒙的地方

    1.根据路由进行菜单展示
    代码位置:/src/components/sideMeuns.vue,
    先看下elementUI菜单组件,把一些基础的参数先了解一下,
    这里我把菜单渲染写成了一个组件:
    用到了递归属性,保证可以生成多级菜单,
    我建议不熟悉的,大家用组件先模拟着写一个包含跳转功能、icon展示的菜单,然后再看我写的组件

    2.用户退出系统
    代码位置:/src/components/layout.vue
    退出的时候,记得清除掉存在localStorage的用户角色,
    然后利用 window.location.href = "/"跳转到登录页,

    为什么要用location.href,这样会把之前addRoutes的路由清除掉,确保下个用户登陆后,会重新渲染正确的菜单

    如果有些地方不理解,师兄建议把不理解的点先单独拿出来跑跑,
    或者看看这篇文章的思路来源:手把手...

    如有不正确的地方,还望小伙伴指正哈

  • 相关阅读:
    虚拟化VMware之虚拟机备份(1)
    虚拟化VMware之虚拟机备份(1)
    柯塔娜大合唱,互联网安全观
    柯塔娜大合唱,互联网安全观
    如何在虚拟机上Centos系统安装Nginx服务
    给已验证登录的用户添加访问限制
    Python爬虫入门教程 23-100 石家庄链家租房数据抓取
    login_required装饰器(1)
    Oracle 18c 新特性:动态 Container Map 增强 Application Container 灵活性
    如果登录不成功,跳转到登录页面
  • 原文地址:https://www.cnblogs.com/onesea/p/13167238.html
Copyright © 2011-2022 走看看