The whole process

Implementation effect

Different user login displays different side route navigation

The code has been uploaded to Github

The code address

process

Use router.addRoute to dynamically add the route to the routing document. Use router.getRoutes to read the routing document.

Pay attention to the point

  • Routing version:"Vue - the router" : "^ 3.2.0",
  • It’s officially abandonedaddRoutes
  • Should currently be usedaddRoute!!!!!!!!!

  • Get routing functionrouter.getRoutes()The returned array will not have a hierarchy and will carry the child routes to the outermost layer.

Introduction to core code

// Simulate the route sent from the back end
export const authRouter = [
  {
    path: '/allSeePage'.name: 'Visible to all'.component: 'allSeePage' // require([' @/views/${view} '], resolve
  },
  {
    path: '/adminPage'.name: 'Administrator Visible'.component: 'adminPage'}]Copy the code

I have logged in, logged out, added routes and methods in VUEX

1, the state

  state: {
    userInfo: {
      userName: ' '.password: ' '.token: ' '.routerList: [] // Store the route list returned by the back end}},Copy the code

2. Add route method ADD_ROUTE to vuEX

vuex-mutaions

mutations: {
    ADD_ROUTE(state) {
      let routerList = JSON.parse(JSON.stringify(state.userInfo.routerList))
      console.log(26, router.getRoutes().length)
      // There are 4 routes before the route is added, and 6 routes after the route is added
      if (router.getRoutes().length < 6) {
        routerList = filterAsyncRouter(routerList)// Add routes dynamically
        console.log('Before adding route', router.getRoutes())
        routerList.forEach((i) = > {
          // Add a child route to the parent route
          router.addRoute('home', i)
        })
        console.log('Route added', router.getRoutes())
      }
    }
}
Copy the code

2,

Basically read the login interface route and add the route to it

  • vuex
 state: {
    userInfo: {
      userName: ' '.password: ' '.token: ' '.routerList: [].// Route list of the current logged-in user - sent from the back end}},mutations: {
    SET_USER_INFO(state, val) {
      state.userInfo = Object.assign(state.userInfo, val)
    }
  },
actions: {
    / / login
    login({ commit }, userInfo) {
      const { userName, password } = userInfo
      return new Promise((resolve) = > {
        // Simulate login, get user information, permission routing list
        // If the token is returned, the route list will be different for different users.
        / * * * * * * * * * * * * * * * * * * * * * * to get their routing list - analog back-end S * * * * * * * * * * * * * * * * * * * * * * * /
        let routerList = []
        if (userName === 'admin') {
          routerList = authRouter
        } else if (userName === 'commonUser') {
          routerList = [authRouter[0]]}/ * * * * * * * * * * * * * * * * * * * * * * to get their routing list - analog back-end E * * * * * * * * * * * * * * * * * * * * * * * /
        let token = 'testToken'
        // Store user information to vuex
        commit('SET_USER_INFO', {
          userName,
          password,
          token,
          routerList
        })
        // Add a route
        commit('ADD_ROUTE')
        resolve()
      })
    },
}
Copy the code

3, the cancellation

vuex-actions

actions:{
    / / logout
    logout({ commit, state }) {
      return new Promise((resolve) = > {
        console.log(state.userInfo.token, 'Logged out')
        commit('SET_USER_INFO', {
          userName: ' '.password: ' '.token: ' '
        })
        // Reset the route
        resetRouter() // This is the route in the reset method, introduced
        resolve()
      })
    },
}
Copy the code

4. Render menu

With router.getroutes (), get the added route. This method makes all the layers one layer, and the child routes are rendered to the page with the parent attribute

In the left navigation component

      let routeList = this.$router.getRoutes()
      // Find the child routes of the home route and render them
      this.menuList = routeList.filter(
        (i) = > i.parent && i.parent.name === 'home'
      )
Copy the code
  • Resetting routing methods

permission.js

// Create a route
const createRouter = () = >
  new VueRouter({
    scrollBehavior: () = > ({ y: 0 }),
    routes: constantRoutes
  })
  // Reset the route
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // reset router
}

export const router = createRouter()

Copy the code

Routing hook functionbeforeEach

process

code

router.beforeEach(async (to, from, next) => {
  // Get user information
  let { userInfo } = store.state
  const { userName } = userInfo
  console.log('User roles', userName ? userName : 'Not landed')
  // There is user information
  if (userName) {
    await store.dispatch('addRoute')
    let { routerList } = userInfo
    // If to.name is a dynamic route, does anyone know of a better way to do this?
    if(! to.name) {// The current route is dynamic. If it exists, jump to 404. If it does not, jump to 404
      if (routerList.findIndex((i) = >i.path === to.path) ! = = -1) { next({ ... to,replace: true})}else {
        next('/ 404')}}else {
      next()
    }
  }
  // No user information
  else {
    // Without permission access, jump to no permission page/or login page
    // Check whether the interface needs to be jumped before jumping, otherwise it will enter an infinite loop
    if (to.path === '/login') {
      next()
    } else {
      Message.error('Please login first! ')
      next('/login')}}})Copy the code

Dynamic routingcomponentThe introduction of

export const loadView = (view) = > {
  // Route lazy loading
  return (resolve) = > require([`@/views/${view}`], resolve)
}
Copy the code

In the pit of

1, the vue – the route: 3 x version, abandoned the router. AddRoutes, instead of using the router. AddRoute, note no. 2, the router s getRoutes access layer routing hierarchy is only one! There will be no child routes, the child routes will have the parent attribute. Do not use this.$router.options.routes to retrieve routes. 4. After route F5 is refreshed, routes that are dynamically added before are lost. 404 page, the hook function to determine the good. {path: ‘*’, redirect: ‘/404’}

Can refer to flower underpants big guy’s question

Write in the last

  • There may be a Bug in the code, hope to raise it in warehouse issues
  • inbeforeEachIs there a better way to do that?
  • The code address
  • Thank you for reading.