RBAC permission design – Background Administration – Page level permission application – Using dynamic add route addRoutes method will appear bugs and solutions

In order to achieve the goal that different accounts can see different pages and perform different functions after logging in to the system, we have a variety of solutions, RBAC(Role-based Access Control) permission model, also known as role-based Access control solution, let’s talk about permission applications

To dynamically addRoutes according to roles, you can use the related API — addRoutes() method to dynamically addRoutes

AddRoutes basic use

Router. AddRoutes ([Routing configuration object]) or:this.$router. AddRoutes ([Router Configuration object])Copy the code

The sample

/ / button
<button @click="hAddRoute">addRoute</button>

/ / callback
hAddRoute() {
	this.$router.addRoutes([{
		path: '/abc'.component: () = > import('@/views/abc'),}}]),Copy the code

After clicking the button, you can access the/ABC page in the address

  1. Delete the dynamic routes that are directly added in the routing configuration rules in the Router folder

    const createRouter = () = > new Router({
      // mode: 'history', // require service support
      scrollBehavior: () = > ({ y: 0 }),
      // routes: constantRoutes
      // Merge dynamic and static routes... asyncRoutes
    - routes: [...constantRoutes, ...asyncRoutes]
    + routes: [...constantRoutes]
    })
    Copy the code
  2. [router. AddRoutes] [router. AddRoutes] [router. AddRoutes] [router.

    Route front guard, with token to enter the home page

    // router.addroutes ([Router configuration object])
    // Import static routes
    import { constantRoutes } from '@/router/index'
    
    // Filter dynamic routes based on roles' permissions
    const menus = store.state.user.userInfo.roles.menus
    const filterasyncRoutes = asyncRoutes.filter(item= > {
      return menus.includes(item.children[0].name)
    })
            
    router.addRoutes(filterasyncRoutes)
    
    await store.commit('menus/setMenusList', filterasyncRoutes)
    Copy the code
  3. (Solution to problem 1) Static routes and dynamic routes can be combined in VUEX to generate a menu bar through VUEX. Different roles have different permissions, so dynamic routes can be seen in different pages

    // Import static route constantRoutes
    import { constantRoutes } from '@/router/index'
    
    export default {
      namespaced: true.state() {
        return {
          menusList: [...constantRoutes]
        }
      },
      mutations: {
        setMenusList(state, val) {
          state.menusList = [...constantRoutes, ...val]
        }
      }
    }
    Copy the code

The following bugs occur when using the addRoutes method

Refresh the browser and jump back to page 404

why

{ path: The '*'.redirect: '/ 404'.hidden: true }
Copy the code

404 page In the static route, the dynamic route is joined to the dynamic route, so the 404 page is displayed first

The solution

Delete route rule 404 from static route and add it to the end of dynamic route

// router.addroutes ([Router configuration object])
// Import static routes
import { constantRoutes } from '@/router/index'

// Filter dynamic routes based on roles' permissions
const menus = store.state.user.userInfo.roles.menus
const filterasyncRoutes = asyncRoutes.filter(item= > {
  return menus.includes(item.children[0].name)
})

// Add the 404 page to the end
filterasyncRoutes.push({ path: The '*'.redirect: '/ 404'.hidden: true })
        
router.addRoutes(filterasyncRoutes)

await store.commit('menus/setMenusList', filterasyncRoutes)
Copy the code

2. A blank screen will appear when the page is refreshed

The solution

Add to next() in the route front guard

if (store.state.user.userInfo.userId) {
  next()
} else {
  // ...     
    
  // Fix the blank screen bug when refreshingnext({ ... to,// next({ ... To}) to ensure that the route is added before entering the page.
    replace: true // Reprogress once without retaining repeated history})}Copy the code

Menu exception – Console error route repetition

why

Router. AddRoutes (filterRoutes) added router. AddRoutes (filterRoutes)

You need to reset the route permission (restore the default) and add it again after logging in. Otherwise, it will be added repeatedly

The solution

// Reset the route
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // Reset the matching path of the route
}
Copy the code

This method is to re-instantiate the route, equivalent to changing a new route, the previous route does not exist, need to log out of the time, call the **