Permission control is an indispensable part when developing a background management system. This article will introduce in detail how to use Vue to generate routes dynamically according to different roles, thereby controlling user access rights.
Step 1: Basic routing configuration
First, we need to configure basic routes, which are shared by all users, such as login pages and 404 pages.
const allRoutes = [ // Basic routing { path: '/', name: 'login', component: () => import("@/views/") }, { path: '/404', name: '404', component: () => import('@/views/Error/') }, // Dynamic routing container (content after login) { path: '/layout', name: 'layout', component: () => import('@/Layout/'), children: [] }, ]
Step 2: Complete routing data
Next, create an array containing all possible routes. This array will be used to compare the permission data returned by the backend to filter out the routes that the current user has permission to access.
// All routesconst totalRoute = [ { path: '/', name: 'login', component: () => import("@/views/") }, { path: '/404', name: '404', component: () => import('@/views/Error/') }, { path: '/layout', name: 'layout', component: () => import('@/Layout/'), }, { path: '/home', name: 'front page', id: 1, pid: 0, }, { id: 2, pid: 0, redirect: null, path: '/comp', name: 'Outpatient', children: [{ id: 3, pid: 2, redirect: null, component: () => import('@/views/'), path: "/pay", name: "Outpatient payment record", },{ id: 4, pid: 2, redirect: null, component: () => import('@/views/'), path: "/reservation", name: "Appointment Record", }] }, { id: 8, pid: 0, path: '/hospital', name: 'Hospital', children: [{ id: 9, pid: 8, redirect: null, component: () => import('@/views/'), path: "/hospitalpay", name: "Hospital payment record", },{ id: 10, pid: 8, redirect: null, component: () => import('@/views/'), path: "/room", name: "Room Management", },{ id: 11, pid: 8, redirect: null, component: () => import('@/views/'), path: "/inpatient", name: "Inpatient", }] } ];
Step 3: Simulate backend permission data
For demonstration, we use simulated data to represent permission information returned by the backend.
Then there is the data returned by the backend interface, so I will use fake data instead. The basic routing and false data should be consistent. Fake data is dynamic routing (which will change)
// Dynamic accessconst dynamicRouteConfigs = [ // Dynamic routing container (content after login) { path: '/home', name: 'front page', id: 1, pid: 0, }, { id: 2, pid: 0, redirect: null, path: '/comp', name: 'Outpatient', children: [{ id: 3, pid: 2, redirect: null, path: "/pay", name: "Outpatient payment record", },{ id: 4, pid: 2, redirect: null, path: "/reservation", name: "Appointment Record", }] }, { id: 8, pid: 0, path: '/hospital', name: 'Hospital', children: [{ id: 9, pid: 8, redirect: null, path: "/hospitalpay", name: "Hospital payment record", },{ id: 10, pid: 8, redirect: null, path: "/room", name: "Room Management", },{ id: 11, pid: 8, redirect: null, path: "/inpatient", name: "Inpatient", }] }, { id: 12, pid: 0, redirect: null, path: '/userinfor', name: 'User Management', children: [{ id: 13, pid: 12, redirect: null, path: "/user", name: "User Management", },{ id: 14, pid: 12, redirect: null, path: "/role", name: "Role Management", },{ id: 15, pid: 12, redirect: null, path: "/admin", name: "Administrator Management", },{ id: 27, pid: 12, redirect: null, path: "/visit", name: "Medical Card", }] }, { id: 16, pid: 0, path: '/department', name: 'Department Management', children: [{ id: 24, pid: 16, redirect: null, path: "/departments", name: "Department Management", }] }, { id: 17, pid: 0, path: '/hospitals', name: 'Hospital Information', redirect: null, children: [{ id: 18, pid: 17, redirect: null, path: "/hospitalList", name: "Hospital Information", },{ id: 19, pid: 17, redirect: null, path: "/doctor", name: "Doctor Management", },{ id: 20, pid: 17, redirect: null, path: "/scheduling", name: "Doctor Schedule Management", },{ id: 21, pid: 17, redirect: null, path: "/label", name: "Tag management", },{ id: 22, pid: 17, redirect: null, path: "/drug", name: "Drug Management", }, { id: 23, pid: 17, redirect: null, path: "/physical", name: "Physical Examination Management", },{ id: 26, pid: 17, redirect: null, path: "/trends", name: "Hospital News", }] } ];
Step 4: Create a routing instance
Use Vue Router to create a routing instance and initialize the registered underlying route.
// Create a routing instanceconst router = createRouter({ history: createWebHistory(.BASE_URL), routes: allRoutes })
Step 5: Filter the matching routes
Write a function to filter out matching routes. This function will traverse the permission data returned by the backend and the complete routing data, find the matching routes and add components.
- Then make a change judgment, and by traversing the two arrays, and when the name or path of the two are the same, put it into a new array.
- Then declare a variable equal to component, which is to add the component component component of the basic route
const filterRoutes = (dynamicRouteConfigs, totalRoute) => { // Print dynamic routing configuration ('Dynamic Routing', dynamicRouteConfigs); // Print total route ('Basic Routing', totalRoute); // Define a recursive function findMatchedRoute, which is used to find matching target routes in route arrays const findMatchedRoute = (routes, target) => { // traverse the route array for (const route of routes) { // If the route name is in the exclusion list, skip if (['404', 'home'].includes()) continue; // If the route name or path matches the target, return the route if ( === || === ) { return route; } // If the current route has a subroutine, recursively look up the matching subroutine if () { const matchedChild = findMatchedRoute(, target); // If a matching subroutine is found, return if (matchedChild) return matchedChild; } } // If no matching route is found, return null return null; }; // Define a function mergeRoutes to merge source routes and match routes const mergeRoutes = (source, target) => { // Return a new routing object, containing all attributes of the source route, and component attributes that match the route return { ...source, component: , // If the source route has a subroutine, recursively merge the subroutine children: ? (child => mergeRoutes(child, findMatchedRoute([target], child) || {})) : undefined, // Other possible contents can be merged here, such as meta attributes }; }; // Map dynamic routing configurations to match and merge each route const result = dynamicRouteConfigs .map(route => { // Find matching routes const matchedRoute = findMatchedRoute(totalRoute, route); // Print matching routes (matchedRoute); // If a matching route is found, merge the route, otherwise return null return matchedRoute ? mergeRoutes(route, matchedRoute) : null; }) // Filter out the null value in the result .filter(route => route !== null); // Print the filtered route array ('Filtered route array:', result); // Return the filtered route array return result; };
Step 6: Dynamically add routes
Write a function to dynamically add filtered routes to the underlying routelayout
In the container.
Then the background control route is completed. The main thing is the same as that section of control, both of which require a basic routing array. After we compare and filter the array, we need to add the filtered array to the route. The logic is the same, just clear the logic.
It’s just that the interfaces that control routing in front and back ends are different.
// Dynamically add routes to layoutconst addDynamicRoutes = (roles) => { // Clear existing dynamic routes const layout = ().find(r => === 'layout') (child => { () }) // Filter and add new routes const allowedRoutes = filterRoutes(dynamicRouteConfigs, allRoutes); (route => { ('layout', route); }); (allowedRoutes); ('menuPath',(allowedRoutes));//Stored filtered dynamic route // Make sure 404 is finally processed ({ path: '/:pathMatch(.*)*', redirect: '/404' }) }
Step 7: Store and render menus
Store the filtered routes in the session storage and render them on the menu page.
Through the above steps, we have completed the settings of permission control and dynamic routing based on Vue. Users of different roles will see different menus and pages, realizing refined management of permissions.
Finally, the route navigation guard will be OK.
//Router Guard Modification Part (router/)(async (to, from, next) => { const store = loginStore() const isLogin = !! // Not logged in status processing if (!isLogin) { return === '/' ? next() : next('/') } // Redirect when logged in but accessing the login page if ( === '/') { return next('/home') } // Dynamic routing loading logic if (!) { try { // Get saved role information directly from the store const userRoles = ; // If the role information does not exist, an error will be thrown if (!userRoles || === 0) { throw new Error('User role information not obtained') } // Add dynamic routing addDynamicRoutes(dynamicRouteConfigs) // Print after adding the route ('Current all routes:', ().map(r => )) // Update load status (true) // Use replace to avoid repeated history recording return next({ ...to, replace: true }) } catch (error) { ('Route loading failed:', error) // Clear the user status and jump to the login page store.$reset() return next('/') } } next(); })
Summarize
This article introduces how to use Vue and Vue Router to implement permission control of the backend management system. By dynamically generating routes, we can flexibly control page access rights based on the user's role, improving the security and user experience of the system.
This is the article about the implementation of permission control and dynamic routing of Vue backend management system. For more related contents of Vue permission control and dynamic routing, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!