Vue后台管理系统权限控制与动态路由的实现
作者:聂聂脸
在开发后台管理系统时,权限控制是不可或缺的一部分。本文将详细介绍如何使用Vue实现根据不同角色动态生成路由,从而控制用户访问权限。
步骤一:基础路由配置
首先,我们需要配置基础路由,这些路由是所有用户共有的,例如登录页和404页。
const allRoutes = [ // 基础路由 { path: '/', name: 'login', component: () => import("@/views/LoginView.vue") }, { path: '/404', name: '404', component: () => import('@/views/Error/404View.vue') }, // 动态路由容器(登录后内容) { path: '/layout', name: 'layout', component: () => import('@/Layout/MainLayout.vue'), children: [] }, ]
步骤二:完整路由数据
接下来,创建一个包含所有可能路由的数组。这个数组将用于与后端返回的权限数据对比,以筛选出当前用户有权访问的路由。
// 所有路由 const totalRoute = [ { path: '/', name: 'login', component: () => import("@/views/LoginView.vue") }, { path: '/404', name: '404', component: () => import('@/views/Error/404View.vue') }, { path: '/layout', name: 'layout', component: () => import('@/Layout/MainLayout.vue'), }, { path: '/home', name: '首页', id: 1, pid: 0, }, { id: 2, pid: 0, redirect: null, path: '/comp', name: '门诊', children: [{ id: 3, pid: 2, redirect: null, component: () => import('@/views/payView.vue'), path: "/pay", name: "门诊缴费记录", },{ id: 4, pid: 2, redirect: null, component: () => import('@/views/reservationView.vue'), path: "/reservation", name: "预约记录", }] }, { id: 8, pid: 0, path: '/hospital', name: '住院', children: [{ id: 9, pid: 8, redirect: null, component: () => import('@/views/hospitalView.vue'), path: "/hospitalpay", name: "住院缴费记录", },{ id: 10, pid: 8, redirect: null, component: () => import('@/views/roomView.vue'), path: "/room", name: "房间管理", },{ id: 11, pid: 8, redirect: null, component: () => import('@/views/inpatientView.vue'), path: "/inpatient", name: "住院人", }] } ];
步骤三:模拟后端权限数据
为了演示,我们使用模拟数据来代表后端返回的权限信息。
然后是后端接口返回的数据,我就先用假数据进行代替了。配置的基础路由和假数据要一致就行。假数据就是动态路由(会发生改变的)
// 动态访问 const dynamicRouteConfigs = [ // 动态路由容器(登录后内容) { path: '/home', name: '首页', id: 1, pid: 0, }, { id: 2, pid: 0, redirect: null, path: '/comp', name: '门诊', children: [{ id: 3, pid: 2, redirect: null, path: "/pay", name: "门诊缴费记录", },{ id: 4, pid: 2, redirect: null, path: "/reservation", name: "预约记录", }] }, { id: 8, pid: 0, path: '/hospital', name: '住院', children: [{ id: 9, pid: 8, redirect: null, path: "/hospitalpay", name: "住院缴费记录", },{ id: 10, pid: 8, redirect: null, path: "/room", name: "房间管理", },{ id: 11, pid: 8, redirect: null, path: "/inpatient", name: "住院人", }] }, { id: 12, pid: 0, redirect: null, path: '/userinfor', name: '用户管理', children: [{ id: 13, pid: 12, redirect: null, path: "/user", name: "用户管理", },{ id: 14, pid: 12, redirect: null, path: "/role", name: "角色管理", },{ id: 15, pid: 12, redirect: null, path: "/admin", name: "管理员管理", },{ id: 27, pid: 12, redirect: null, path: "/visit", name: "就诊卡", }] }, { id: 16, pid: 0, path: '/department', name: '科室管理', children: [{ id: 24, pid: 16, redirect: null, path: "/departments", name: "科室管理", }] }, { id: 17, pid: 0, path: '/hospitals', name: '医院信息', redirect: null, children: [{ id: 18, pid: 17, redirect: null, path: "/hospitalList", name: "医院信息", },{ id: 19, pid: 17, redirect: null, path: "/doctor", name: "医生管理", },{ id: 20, pid: 17, redirect: null, path: "/scheduling", name: "医生排班管理", },{ id: 21, pid: 17, redirect: null, path: "/label", name: "标签管理", },{ id: 22, pid: 17, redirect: null, path: "/drug", name: "药品管理", }, { id: 23, pid: 17, redirect: null, path: "/physical", name: "体检管理", },{ id: 26, pid: 17, redirect: null, path: "/trends", name: "医院动态", }] } ];
步骤四:创建路由实例
使用Vue Router创建路由实例,并初始化注册基础路由。
// 创建路由实例 const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: allRoutes })
步骤五:筛选匹配路由
编写一个函数来筛选出匹配的路由。这个函数将遍历后端返回的权限数据和完整路由数据,找出匹配的路由并添加组件。
- 然后就进行改变判断,通过遍历两个数组,判断两者的name或者path相同的时候将其放入一个新数组中。
- 然后再声明一个变量等于component,就是添加基础路由的component组件
const filterRoutes = (dynamicRouteConfigs, totalRoute) => { // 打印动态路由配置 console.log('动态路由', dynamicRouteConfigs); // 打印总路由 console.log('基础路由', totalRoute); // 定义一个递归函数findMatchedRoute,用于在路由数组中查找匹配的目标路由 const findMatchedRoute = (routes, target) => { // 遍历路由数组 for (const route of routes) { // 如果路由名称在排除列表中,则跳过 if (['404', 'home'].includes(route.name)) continue; // 如果路由名称或路径与目标匹配,则返回该路由 if (route.name === target.name || route.path === target.path) { return route; } // 如果当前路由有子路由,则递归查找匹配的子路由 if (route.children) { const matchedChild = findMatchedRoute(route.children, target); // 如果找到匹配的子路由,则返回 if (matchedChild) return matchedChild; } } // 如果没有找到匹配的路由,则返回null return null; }; // 定义一个函数mergeRoutes,用于合并源路由和匹配的路由 const mergeRoutes = (source, target) => { // 返回一个新的路由对象,包含源路由的所有属性,以及匹配路由的component属性 return { ...source, component: target.component, // 如果源路由有子路由,则递归合并子路由 children: source.children ? source.children.map(child => mergeRoutes(child, findMatchedRoute([target], child) || {})) : undefined, // 可以在这里合并其他可能需要的内容,例如meta属性 }; }; // 映射动态路由配置,对每个路由进行匹配和合并操作 const result = dynamicRouteConfigs .map(route => { // 查找匹配的路由 const matchedRoute = findMatchedRoute(totalRoute, route); // 打印匹配的路由 console.log(matchedRoute); // 如果找到匹配的路由,则合并路由,否则返回null return matchedRoute ? mergeRoutes(route, matchedRoute) : null; }) // 过滤掉结果中的null值 .filter(route => route !== null); // 打印过滤后的路由数组 console.log('过滤后的路由数组:', result); // 返回过滤后的路由数组 return result; };
步骤六:动态添加路由
编写一个函数来动态添加筛选后的路由到基础路由的layout
容器中。
然后后台控制路由就完成了。主要和起那段控制是一样的,都是需要一个基础的路由数组,然后我们将数组对比过滤过之后,需要把过滤好的数组添加注册到路由中。逻辑都是一样的,疏通逻辑就可以了。
只不过前后端控制路由的接口返回不一样而已。
// 动态添加路由到layout const addDynamicRoutes = (roles) => { // 清空已有动态路由 const layout = router.getRoutes().find(r => r.name === 'layout') layout.children.forEach(child => { router.removeRoute(child.name) }) // 过滤并添加新路由 const allowedRoutes = filterRoutes(dynamicRouteConfigs, allRoutes); allowedRoutes.forEach(route => { router.addRoute('layout', route); }); console.log(allowedRoutes); sessionStorage.setItem('menuPath',JSON.stringify(allowedRoutes));//存储的筛选过的动态路由 // 确保404最后处理 router.addRoute({ path: '/:pathMatch(.*)*', redirect: '/404' }) }
步骤七:存储和渲染菜单
将筛选后的路由存储在会话存储中,并在菜单页面进行渲染。
通过以上步骤,我们完成了基于Vue的后台管理系统权限控制与动态路由的设置。不同角色的用户将看到不同的菜单和页面,实现了权限的精细化管理。
最后路由导航守卫加上去就ok了。
// 路由守卫修改部分(router/index.ts) router.beforeEach(async (to, from, next) => { const store = loginStore() const isLogin = !!store.id // 未登录状态处理 if (!isLogin) { return to.path === '/' ? next() : next('/') } // 已登录但访问登录页时重定向 if (to.path === '/') { return next('/home') } // 动态路由加载逻辑 if (!store.routesLoaded) { try { // 直接从store获取已保存的角色信息 const userRoles = store.roles; // 如果角色信息不存在则抛出错误 if (!userRoles || userRoles.length === 0) { throw new Error('用户角色信息未获取') } // 添加动态路由 addDynamicRoutes(dynamicRouteConfigs) // 在添加路由后打印 console.log('当前所有路由:', router.getRoutes().map(r => r.path)) // 更新加载状态 store.setRoutesLoaded(true) // 使用replace方式跳转避免重复记录历史 return next({ ...to, replace: true }) } catch (error) { console.error('路由加载失败:', error) // 清除用户状态并跳转登录页 store.$reset() return next('/') } } next(); })
总结
本文介绍了如何使用Vue和Vue Router实现后台管理系统的权限控制。通过动态生成路由,我们可以根据用户的角色灵活控制页面访问权限,提高系统的安全性和用户体验。
到此这篇关于Vue后台管理系统权限控制与动态路由的实现的文章就介绍到这了,更多相关Vue 权限控制与动态路由内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!