Dynamic routing based on iview-admin

Keywords: Javascript Vue iOS github Database

iview-admin It is a management background front end based on vue and iView component library. Based on the latest version of iview-admin, this paper implements dynamic routing loading based on privilege.
For the code in this article, see: https://github.com/MayBeWrong...

Background:

Dynamic routing: The route of vue can be defined by the new Router incoming route array, or by router.addRoutes. It is called dynamic routing by router.addRoutes dynamically passing in route definition. Routing data can be stored in the background database, or can be configured in the front-end, the back-end return to the front-end routing permission information, and then match filtering, loading. In this paper, the two methods are introduced separately, and the implementation reference is given.

Objectives:
Based on iview-admin Latest code Two different dynamic loading methods are implemented:

  1. Routing (navigation menu) data are all stored in the background
  2. Routing data configuration is in the front end, and only privilege information is stored in the background.

Note: This article simulates the back-end interface through Mock

Mode 1: Routing (navigation menu) data are stored in the background

  • Define the routing data structure in the file: src/mock/data.js
export const routersData = [{
      path: '/pet',//Access path
      name: 'Pet',//The name of the route, which is related to i18n, needs to be unique
      meta: {
        title: 'Pets',//Title
        hideInMenu: false,//Whether to hide from the left navigation menu
        icon: 'logo-freebsd-devil'//Icon
      },
      component: 'components/main',//Component file path, no Import required
      children: [{//Nested Route
        path: 'cat',
        name: 'Cat',
        meta: {
          title: 'Kitty',
          hideInMenu: false,
          icon: 'ios-cloudy-night'
        },
        component: 'view/pet/cat/Cat.vue'
      }, {
        path: 'dog',
        name: 'Dog',
        meta: {
          hideInMenu: false,
          title: 'Dog baby',
          icon: 'ios-color-filter'
        },
        component: 'view/pet/dog/Dog.vue'
      }, {
        path: 'pig',
        name: 'Pig',
        meta: {
          hideInMenu: false,
          title: 'Pig!',
          icon: 'ios-contact'
        },
        component: 'view/pet/pig/Pig.vue',
        children: [
          {
            path: 'female',
            name: 'Female',
            meta: {
              hideInMenu: false,
              title: 'Sows',
              icon: 'ios-contact'
            },
            component: 'view/pet/pig/Pig.vue',
          },
          {
            path: 'male',
            name: 'Male',
            meta: {
              hideInMenu: false,
              title: 'Boar',
              icon: 'ios-contact'
            },
            component: 'view/pet/pig/Pig.vue',
          }
        ]
      }]}]
      
  • Expose ajax call interface: src/mock/index.js, add:
Mock.mock(/\/sys\/routers/, routersData)

  • Implement an ajax call: add in src/api/routers.js:

     export const getRouterReq = (access) => {
         return axios.request({
           url: '/sys/routers',
           params: {
             access
           },
           method: 'get'
     })}
    
    

1. Define dynamic routing logic in store and modify: src/store/module/app.js

Introduce ajax requests:

    import {getRouterReq} from '@/api/routers'

Define two state s, as follows

state: {
   .....
    routers: [],//Route data obtained
    hasGetRouter: false//Has routing data been taken?
  },

 

Synchronized addition of mutations:

  mutations: {
     ......
     //Setting up routing data
    setRouters(state, routers) {
      state.routers = routers
    },
    //Set whether routing has been taken
    setHasGetRouter(state, status) {
      state.hasGetRouter = status
    }......}

Add an action:

action:{
........
    getRouters({commit}) {
      return new Promise((resolve, reject) => {
        try {
          getRouterReq().then(res => {
            let routers = backendMenusToRouters(res.data)
            commit('setRouters', routers)
            commit('setHasGetRouter', true)
            resolve(routers)
          }).catch(err => {
            reject(err)
          })
        } catch (error) {
          reject(error)
        }
      })
    },
    ........
}

A function is used here: backend Menus ToRouters, which is defined in src/libs/util.js to recursively process the route data returned from the back end and route vue.

export const backendMenusToRouters = (menus) => {
  let routers = []
  forEach(menus, (menu) => {
    // Converting back-end data to routing data
    let route = backendMenuToRoute(menu)
    // If the backend data has a subordinate, the subordinate is processed recursively
    if (menu.children && menu.children.length !== 0) {
      route.children = backendMenusToRouters(menu.children)
    }
    routers.push(route)
  })
  return routers
}


  • Modify src/router/index.js and add dynamic routing join logic. The main methods are as follows:

       const initRouters = (store) => {
     //This person has logged in.
     if (store.state.user.hasGetInfo) {
       //Routing loaded
       if (store.state.app.hasGetRouter && store.state.app.routers && store.state.app.routers.length > 0) {
         console.log("Routing has been loaded")
       } else {
         //Load routing
         console.log("Start loading routing permissions...")
         store.dispatch('getUserMenus').then(routers => {
           //Here routers have been filtered according to the permission of the route, no permission, do not join the route, can not access
           //Route reset, put 404 at the end
           const newRouter = new Router({
             routes,
             mode: config.routerModel
           })
           router.matcher = newRouter.matcher;
           //Add 404 to the end, and if you use router.push({name:'xxxx'}), the 404 page may be blank, using path:'/aa/bb'
           router.addRoutes(routers.concat([{
             path: '*',
             name: 'error_404',
             meta: {
               hideInMenu: true
             },
             component: () => import(/* webpackChunkName: "404" */'@/view/error-page/404.vue')
           }]))
         }).finally(() => {
         })
       }
     }}
    

Before each routing load, it is determined whether the system routing has been initialized or not.
So far, dynamic routing is basically implemented. The article may have omissions and shortcomings, welcome to discuss. The second way of realization
For specific implementation, see: https://github.com/MayBeWrong...

Posted by wikedawsum on Sun, 06 Oct 2019 13:04:01 -0700