The introduction

When doing background system, it is inevitable that there will be user authority judgment. Admin can view all menus, while user can view only some menus.

When we first approached this requirement, it was purely front-end. When configuring a route, add a roles attribute to determine whether the user’s roles matches the roles attribute of the route

 {
  path: '/router'.name: 'router'.meta: {
    title: 'title'.roles: ['admin'.'user']},component: index,
  children: [{path: 'children'.name: 'children'.meta: {
        title: 'Subheading'.roles: ['admin'.'user']},component: child
    }
  ]
}
Copy the code
// Filter routes menuList- menu roles- User roles
const checkMenuList = (menuList, roles) = > {
  for (let i = 0; i < menuList.length; i++) {
    if(! compareEqual(roles, menuList[i].meta.roles) || menuList[i].meta.noRenderTree) { menuList.splice(i,1)
      i -= 1
    } else {
      if (menuList[i].children) {
        checkMenuList(menuList[i].children, roles)
      }
    }
  }
  return menuList
}
Copy the code

This does make it possible to show different menus to different users. But if user permissions change, the front end needs to issue a version. In line with the principle that all things can be flexibly configured.

demand

First of all, we need to understand what we’re going to do.

We hope that we can flexibly configure the routing permissions through the user permission configuration function, so that the server can return the routing permissions to be displayed and the front end can display them.

Train of thought

  1. The front end configures routes for all pages of the project
  2. The server side returns the user’s permission list, the front end matches, and finally returns a route list as a menu
  3. For better user experience, when a user enters an abnormal route, we redirect to a 404 page, indicating that the page does not exist.
  4. Based on point 3, we also need to judge whether the page exists and whether the user has the permission to jump every time we jump

implementation

Ok, that’s it. Start implementing it now!

First of all, routers need to be registered at the front end. We need to configure the entire page of the routers first.

In addition to the system menu, we also need to configure 403 error page, as well as login, home page and other basic routes. The system menu also needs to match the route list returned by the server, so registration is not performed for the time being

// router.js

 // Basic routing
export const defaultRouter = [
  { path: '/'.component: index }, / / home page
  { path: '/login'.name: 'login'.component: login } / / login page
 ]
 
 // All pages of the project
export const appRouter = [
   {
    path: '/router1'.name: 'router1'.redirect: '/router1/test1'.component: router1,
    meta: { title: 'route 1'},
    children: [{path: 'test1'.name: 'test1'.component: test1, meta: { title: Test '1'}}, {path: 'test2'.name: 'test2'.component: test1, meta: { title: 'test 2'}}]},]// This is the routes registered when our page is initialized
const routers = [ 
  ...defaultRouter
]
const RouterConfig = {
  routes: routers
}
const router = new VueRouter(RouterConfig)
Copy the code

After all routes are registered, the next step is to match routes accessible to users. This step needs to be agreed with the server side.

Route name: with or without permission authRouter:{'test1': false.'test2': true
}
Copy the code

Once you get the user permissions returned from the server, you start filtering routes

// appRouterCopy- authRouter- permission list const checkMenuList = (appRouterCopy, authRouter) => {for (let i = 0; i < appRouterCopy.length; i++) {
        let {name, children} = appRouterCopy[i]
        if (authRouter[name] === false) {
            appRouterCopy.splice(i, 1)
            i--
        } else if (children && children.length) {
            checkMenuList(children, authRouter)
        }
    }
}
Copy the code

Once you have the filtered route, you register it with addRoutes. Note that the 404 route configuration is added at the end.

let error404Page = { path: '/ *', name: 'error-404', meta: { title: '404- Page not found '}, component: error404Page}
router.addRoutes([...appRouterCopy, error404Page])
Copy the code

At this point we have a page with user permissions and can render the resulting list as a system menu. The next step is to deal with the jump exception. You need to use beforeEach to intercept each jump

router.beforeEach(((to, from, next) => {
    if(isNotLog && to.name ! = ='login') {// No login jump to login page next({name:'login'})}else if (to.name && (to.name === 'login' || to.name.indexOf('error')! == -1) {// next()}elseCheckUser (next, to,router)}}) const checkUser = async (next, to,router) => {// checkUser(next, to,router)}}) const checkUser = async (next, to,router) => {if(isNotUser) {// Login to the system for the first time, Const authRouter = getAuthRouter() // Obtain user permission checkMenuList(appRouterCopy, authRouter) const error404Page = { path:'/ *', name: 'error-404', meta: { title: '404- Page not found '}, component: error404Page}
        router.addRoutes([...appRouterCopy, error404Page])
        if(! Approutercopy.length) {// users without permission can jump to 404 or login page next({... error404Page, replace:true})}else{ next({ ... to, replace:true}}})else {
        next()
    }
}
Copy the code