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:
- Routing (navigation menu) data are all stored in the background
- 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...