Implementation scheme of Vue dynamic menu (routing) (beforeEach + addRoutes + elementUI)

github address

02 Foreword

I have summarized the implementation scheme of the dynamic menu> dynamic menu implementation,
but this article is a little more complicated. It is implemented by using the routing table of the backend to return the current login role. Render the menu;

Today, I will explain a solution: the routing table is written on the front end, the back end returns the user's role, and the front end renders the menu corresponding to the role

Online preview: dynamic routing
github (recorded star): https://github.com/Mrblackant…

Insert picture description here
Before you start, you should probably understand the methods of beforeEach (route interception), addRoutes, and elementUI menu components of vue-router, otherwise it may be a bit difficult to understand

02 Idea

It is divided into the following steps:
1. The front end writes the routing table locally, and the role corresponding to each route, that is, which roles can see this menu / route;
2. When logging in, request the back end to obtain the role of the logged-in user (Administrator, ordinary user);
3. Use route interception, according to the role of the user, compare with the local routing table, filter out the route corresponding to the user, and use the route to render the left menu

03 Implementation

According to the above 3 steps, we carry out the realization of each step

1. The front end writes the routing table locally

We are divided into two routing tables, one is fixed, such as the homepage display, everyone can see, one needs to be dynamically displayed according to the user's role;
here we use the router's meta attribute, we write the corresponding menu here : icon, which roles can see this menu: Roles
A complete routing table is as follows:

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

2. The user logs in and gets the user's role

Originally, I wrote mock data, simulated user login, and requested the back-end role interface, but the mock hung up,
so I directly simulated:

Get the user role, store it in localStorage, and then jump to the homepage

//代码位置: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. Route interception beforeEach, and filter out the routing table corresponding to the role

After the second step, we have obtained the role of the user, at this time we can get it in the route interception place,

After getting it, combining the route we wrote in step 1, using the array filtermethod, compare the role with metathe rolessdata in the label in the routing table

After filtering, take the current route to render the menu on the left. This step can actually be implemented with vuex. I am worried that some friends do not understand it, so I use a global(global variable) instead.

Pay particular attention to the route interception here, it is easy to fall into an infinite loop, so I suggest that you first look beforeEachand addRoutesoperation mechanism

//代码位置: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('/')
    }
  }

})

After the whole process is over, it is easy to be confusing

1) Menu display based on routing

Code location: /src/components/sideMeuns.vue,
first look at the elementUI menu component, first understand some basic parameters,
here I wrote the menu rendering as a component: the
use of recursive attributes to ensure that it can generate multi-level menus,
I suggest that you are not familiar with it, everyone use components First simulate to write a menu that includes the jump function and icon display, and then look at the components I wrote

2) The user exits the system

Code location: /src/components/layout.vue
When you log out, remember to clear the user role that exists in localStorage,
and then use window.location.href = "/" to jump to the login page,

Why use location.href, this will clear the previous route of addRoutes, and ensure that the correct menu will be re-rendered after the next user logs in

If some places do not understand, I do not understand the brothers suggested that the first point to separate out running,
or look at the source of the idea for this article: hands-on ...

If there is something wrong, I hope your friends can correct me

note:

Follow the documentation, but after refreshing the page, an error is reported, Error in beforeCreate hook: "RangeError: Maximum call stack size exceeded", how to deal with this?
Pay attention to look here and add judgment,不要一直进入beforeEach里边的添加路由方法
note:

Published 252 original articles · Like 106 · Visits 30,000+

Guess you like

Origin blog.csdn.net/weixin_42554191/article/details/105460002