Access to the background with minimal changes to dynamically load menus based on permissions

Modified code snippet + comment description

import {list as getRoutes} from ‘@/api/admin/menu’
import Layout from ‘@/layout’

generateRoutes({commit}, roles) { return new Promise(resolve => { // Request background data to replace the asyncRoutes asynchronous routing of src/router/index.js getRoutes({mode: 3}).then(response => { / The / filterAsyncRoutes method is used for permission filtering and data conversion. Roles is a set of login user role IDs, such as: [1,2] let accessedRoutes = filterAsyncRoutes(response.data, roles) commit('SET_ROUTES', accessedRoutes) resolve(accessedRoutes) }) }) }









// Recursive permission filtering and data conversion
export function filterAsyncRoutes(routes, roles) { const res = [] routes.forEach(route => { const tmp = {...route} if (hasPermission(roles, tmp)) { const component = tmp.component if (route.component) { if (component =='Layout') { tmp.component = Layout } else { // Convert interface component string to component object tmp.component = (resolve) => require([ ], resolve) } if (tmp.children) { tmp.children = filterAsyncRoutes(tmp.children, roles) } } res.push(tmp) } }) return res }










@/views/${component}









3. Back-end interface

  1. Interface data analysis
    Next, replace the configuration in the asyncRoutes asynchronous routing in the src/router/index.js file through the background interface.

First analyze the data structure of asynchronous routing:

Through the observation and understanding of the asynchronous routing data in the above figure, the following points are obtained:

The path does not have a backslash in front of the sub- route
. AlwaysShow of the root menu is true. The
component component needs to be imported during compilation through import. The interface can only return the component path string, so there must be a component path after the interface request is completed.
The role attribute of meta in the conversion process from string to component object corresponds to the collection of uniquely identified roles with the routing access permission, here I am using the role ID
2. Interface implementation
completes the above data analysis, the next step is the specific implementation of the interface Yes, please click on youlai-mall to pull the SQL and complete code. Only the key code and analysis are posted below.

SysMenuMapper

Get the set of menu list and role ID corresponding to access permissions

SysMenuServiceImpl

Convert the menu into a route, recursively generate a parent-child structure tree

SysMenuController

REST provides external interfaces

  1. Interface test
    Use the interface test tool to test, http://localhost:9999/youlai-admin/menus?mode=3, here is accessed through a gateway. For details, please know that there are youlai-mall projects.

Return the data in its entirety to see if it matches the data format of asyncRoutes.

{ “Code”: “00000”, “data”: [{ “path”: “/admin”, “component”: “Layout”, “alwaysShow”: true, “name”: “System Management”, “meta” : { “Title”: “System Management”, “icon”: “documentation”, “roles”: [2, 1] }, “children”: [{ “path”: “user”, “component”: “admin /user", "alwaysShow": false, "name": "User Management", "meta": { "title": "User Management", "icon": "user", "roles": [1] } } , { “Path”: “role”, “component”: “admin/role”, “alwaysShow”: false, “name”: “role management”, “meta”: { “title”: “role management”,




























“Icon”: “peoples”,
“roles”: [2, 1]
}
}, { “path”: “dept”, “component”: “admin/dept”, “alwaysShow”: false, “name”: “ Department Management", "meta": { "title": "Department Management", "icon": "tree", "roles": [1, 2] } }, { "path": "menu", "component" : “ Admin /menu”, “alwaysShow”: false, “name”: “menu management”, “meta”: { “title”: “menu management”, “icon”: “tree-table”, “roles”: [1, 2] } }, { “path”: “dict”, “component”: “admin/dict”, “alwaysShow”: false, “name”: “Dictionary Management”, “meta”: { “title” : "Dictionary Management",


























“Icon”: “education”,
“roles”: [1, 2]
}
}]
}],
“msg”: “everything ok”
} The
last thing to do is to convert the component path string into a component object Yes, post again the code modified in permission.js above:

if (component =='Layout') { tmp.component = Layout } else { // The interface component string is converted into a component object tmp.component = (resolve) => require([ ], resolve) } There is one thing to note The dynamic import of the above components cannot use import, as follows:



@/views/${component}

tmp.component = () => import( @/views/${component})
otherwise the following error will be reported

Error: Cannot find module'@/views/***' The
reason is that webpack does not support dynamic import of import, but it was possible before, so some people can't figure it out. You can use require to import components dynamically.
Amazon review www.yisuping.com

Guess you like

Origin blog.csdn.net/weixin_45032957/article/details/108616048