Mainstream implementation methods:
Let’s talk about the advantages of the two methods. After all, if you have never done it before, and you can’t understand it no matter how much you say, you still have to read the code
Front-end control
- No backend help is needed, the routing table is maintained on the front end
- The logic is relatively simple and easy to get started
Backend control
- Relatively safer
- Routing table maintenance in the database
1. Front-end control
Idea: In the routing configuration,meta
Attributes, fields related to extension permissions are determined by judging this permission identifier in the route guard to dynamically increase the route and page jump; for example: we add arole
Fields to control roles
Specific plan:
1. Return to the role of the front-end user according to the account of the logged in user.
2. The front-end matches the routing table based on the user's role
3. Make the matched routes to form accessible routes
Core code logic
1. In the file (write static routes and dynamic routes respectively)
import Vue from 'vue' import Router from 'vue-router' (Router) import Layout from '@/layout' // constantRoutes static routes, mainly login pages, 404 pages, etc. that do not require dynamic routesexport const constantRoutes = [ { path: '/redirect', component: Layout, hidden: true, children: [ { path: '/redirect/:path*', component: () => import('@/views/redirect/index') } ] }, { path: '/login', component: () => import('@/views/login/index'), hidden: true }, { path: '/404', component: () => import('@/views/error-page/404'), hidden: true }, { path: '/401', component: () => import('@/views/error-page/401'), hidden: true } ] // asyncRoutes dynamic routingexport const asyncRoutes = [ { path: '/permission', component: Layout, redirect: '/permission/page', alwaysShow: true, name: 'Permission', meta: { title: 'Permission', icon: 'lock', // The core code can be traversed through the matching roles to see if it is displayed // This means two characters: admin and editor. This menu can be displayed roles: ['admin', 'editor'] }, children: [ { path: 'page', component: () => import('@/views/permission/page'), name: 'PagePermission', meta: { title: 'Page Permission', // This means that only admin can display roles: ['admin'] } } ] } ] const createRouter = () => new Router({ scrollBehavior: () => ({ y: 0 }), routes: constantRoutes }) const router = createRouter() // This is used to reset the route, it is very useful, don't look at these few lines of codeexport function resetRouter() { const newRouter = createRouter() = } export default router
2. Store/(maintain a state in vuex, and control whether the menu is displayed by matching roles)
import { asyncRoutes, constantRoutes } from '@/router' // This method is used to match roles andfunction hasPermission(roles, route) { if ( && ) { return (role => (role)) } else { return true } } // This method is to traverse the route through recursion and traverse the authorized routes.export function filterAsyncRoutes(routes, roles) { const res = [] (route => { const tmp = { ...route } if (hasPermission(roles, tmp)) { if () { = filterAsyncRoutes(, roles) } (tmp) } }) return res } const state = { routes: [], addRoutes: [] } const mutations = { SET_ROUTES: (state, routes) => { // This place maintains two states: addRouters and routes = routes = (routes) } } const actions = { generateRoutes({ commit }, roles) { return new Promise(resolve => { let accessedRoutes if (('admin')) { accessedRoutes = asyncRoutes || [] } else { // Core code, pass the route and the obtained role (obtained by the background) to match accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) } // Set the matched permissions to set into vuex commit('SET_ROUTES', accessedRoutes) resolve(accessedRoutes) }) } } export default { namespaced: true, state, mutations, actions }
3、src/
(Create a new route guard function, you can either extract a file in or extract it)
The code here mainly controls the route jump before checking what routes are accessible. The logic for jumping after login can be written in this place
// ((to, from, next) => { if () { // Determine whether there is a token if ( === '/login') { next({ path: '/' }); } else { // Determine whether the current user has pulled the user_info information if ( === 0) { ('GetInfo').then(res => { // Pull info const roles = ; // Pass the obtained role in order to match it, and generate accessed routes ('GenerateRoutes', { roles }).then(() => { // Dynamically add accessible routing tables (core code, nothing can be done without it) () // hack method ensures addRoutes is completed next({ ...to, replace: true }) }) }).catch(err => { (err); }); } else { next() //When you have user permissions, it means that all accessable routes have been generated. If you access the full range of page 404 without permissions will be automatically entered. } } } else { if (() !== -1) { // On the login-free whitelist, enter directly next(); } else { next('/login'); // Otherwise, all will be redirected to the login page } } })
4. The sidebar can take data from vuex for rendering
The core code is fromrouter
Take the available route objects to render the sidebar. Whether it is dynamic loading of the front-end or dynamic loading of the back-end, the code is the same.
<!-- layout/components/ --> <el-menu :default-active="activeMenu" :collapse="isCollapse" :background-color="" :text-color="" :unique-opened="false" :active-text-color="" :collapse-transition="false" mode="vertical" > // Loop the retrieved route to the subcomponent as a parameter <sidebar-item v-for="route in routes" :key="" :item="route" :base-path="" /> </el-menu> // Get permissioned routesroutes() { return this.$ } <!-- layout/components/ --> <template slot="title"> <item v-if="" :icon=" && " :title="" /> </template> <sidebar-item v-for="child in " :key="" :is-nest="true" :item="child" :base-path="resolvePath()" class="nest-menu" /> props: { // route object item: { type: Object, required: true }, isNest: { type: Boolean, default: false }, basePath: { type: String, default: '' } }
The front-end controls routing, and the logic is relatively simple. The back-end only needs to store the user's role, and the front-end matches the user's role. But if new characters are added, it will be very painful and each one needs to be added.
2. Backend control routing
The general idea of back-end control is:The routing configuration is placed in the database table. After the user logs in successfully, the authorized menu is passed to the front-end according to the role permissions, and the front-end is formatted into a structure for page routing recognition, and then rendered to the page menu;
- After the user logs in, the backend directly generates accessible routing data based on the user's role. Note that this place is data.
- The front-end converts the route data returned by the back-end into the route structure it needs.
Specific logic:
- Only some static routes are placed inside.
login
, 404 and so on - Organize a data structure and save it in a table
- Get routing data from the backend, write a data conversion method, and talk about converting the data into accessible routes
- Maintain one
vuex
Status, save the converted route tovuex
in - The sidebar also uses data from the route for rendering
Because the front control and back-end control are mostly the same, this is the only way to look at the previous different processes:
1. Store/, send a request to obtain data in vuex
GenerateRoutes({ commit }, data) { return new Promise((resolve, reject) => { getRoute(data).then(res => { // Convert the retrieved data and save it to vuex const accessedRouters = arrayToMenu() ([{ path: '*', redirect: '/404', hidden: true }]) commit('SET_ROUTERS', accessedRouters) resolve() }).catch(error => { reject(error) }) }) }
2. Organize a data structure and store it in the table
// Page routing format{ path: '/form', component: Layout, children: [ { path: 'index', name: 'Form', component: () => import('@/views/form/index'), meta: { title: 'Form', icon: 'form' } } ] } // Organized data format// Level 1 menu// If parentId is 0, it can be used as a first-level menu. It is best to choose 4 digits of id. As for why you will know when you develop a project.{ id: 1300 parentId: 0 title: "Men Management" path: "/menu" hidden: false component: null hidden: false name: "menu" }, // Level 2 menu// If the parentId is not 0, you can use parentId to match the id of the first-level menu. If the matching is pushed into children{ id: 1307 parentId: 1300 title: "Submenu" hidden: false path: "menuItem" component: "menu/menuItem" // To match the local file address hidden: false name: "menuItem" }
3. Write a conversion method to convert the obtained data into a router structure
export function arrayToMenu(array) { const nodes = [] // Get top-level node for (let i = 0; i < ; i++) { const row = array[i] // This exists method is to determine whether there are children if (!exists(array, )) { ({ path: , // Routing address hidden: , // Just true, if the backend is not matched component: Layout, // Generally, it is the component that matches your file name: , //Route name meta: { title: , icon: }, // title is the name displayed id: , // The routed id redirect: 'noredirect' }) } } const toDo = (nodes) while () { const node = () // Get child nodes for (let i = 0; i < ; i++) { const row = array[i] // The parentId equals the parentId to which parent is pushed if ( === ) { const child = { path: , name: , hidden: , // Core code, because the component of the secondary route needs to match the page component: require('@/views/' + + '/'), meta: { title: , icon: }, id: } if () { (child) } else { = [child] } (child) } } } return nodes } // Check if there are any childrenfunction exists(rows, parentId) { for (let i = 0; i < ; i++) { if (rows[i].id === parentId) return true } return false }
This is the end of this article about the detailed article on the implementation of dynamic routing of vue. For more related content on the implementation of dynamic routing of vue, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!