react的ant-design-pro框架左侧菜单修改为动态路由
在使用 React 框架结合 Ant Design Pro 进行项目开发时,动态路由的修改是一项常见且重要的任务。动态路由能够根据用户的角色、权限或者其他运行时的条件来展示不同的页面内容,极大地提升了应用的灵活性和安全性。本文将结合一个完整的示例项目,详细介绍如何在 Ant Design Pro 中修改动态路由。
在 Ant Design Pro 中使用动态路由的好处包括:
- 灵活性:可以根据条件动态加载路由,适应不同的需求。
- 性能优化:结合懒加载减少初次加载时间,提高性能。
- 可维护性:路由和菜单管理清晰,易于管理和维护。
- 权限控制:可以根据用户角色控制访问权限,增强安全性。
- 用户体验:通过动态路由改善页面跳转体验,提高流畅性
动态路由都需要先在routes中注册页面,然后通过后端对比进行左侧菜单的显示。
下面又开看详细步骤吧!
一. 路由配置(通过access来进行权限验证)。在routes.ts中注册页面路由。
export default [{path: '/user',layout: false,routes: [{name: 'login',path: '/user/login',component: './User/Login',},],},// 首页{path: '/welcome',name: 'welcome',icon: 'HomeOutlined',component: './Welcome',layout: true,hideTitle: false,},// 门诊{path: '/admin',name: 'admin',icon: 'table',hideInBreadcrumb: true, // 添加这行,可以去掉父元素带子级的面包屑routes: [// 这第一个对象的作用就是当点击父级菜单时,默认重定向到父级下的第一个子菜单页面{path: '/admin',redirect: '/admin/sub-page',},// 门诊缴费记录{path: '/admin/sub-page',name: '门诊缴费记录',layout: false,component: './outpatient',},// 预约记录{path: '/admin/subscribe',name: '预约记录',// icon:'SnippetsFilled',layout: false,component: './Subscribe',},],},// 住院{name: 'list',icon: 'ReconciliationFilled',hideInBreadcrumb: true, // 添加这行,可以去掉父元素带子级的面包屑path: '/list',routes: [// 这第一个对象的作用就是当点击父级菜单时,默认重定向到父级下的第一个子菜单页面{path: '/list',redirect: '/list/hospital',layout: false,},// 住院缴费记录{path: '/list/hospital',name: '住院缴费记录',component: './HospitalPrice',layout: false,},// 房间管理{path: '/list/room',name: '房间管理',component: './Room',layout: false,},],},// 用户管理{name: 'user',icon: 'SnippetsFilled',hideInBreadcrumb: true, // 添加这行,可以去掉父元素带子级的面包屑path: '/user',routes: [// 这第一个对象的作用就是当点击父级菜单时,默认重定向到父级下的第一个子菜单页面{path: '/user/user',// redirect: '/user/user',name: '用户管理',component: './user',layout: false,},// 角色管理{path: '/user/role',name: '角色管理',component: './role',layout: false,},// 管理员管理{path: '/user/admin',name: '管理员管理',component: './Manage',layout: false,},// 就诊卡{path: '/user/card',name: '就诊卡',component: './Cards',layout: false,},],},// 科室管理{name: '科室管理',path: '/TableList',icon: 'DiffFilled',access: 'adminRouteFilter',component: './TableList',layout: true,},// 医院信息{name: 'hospital',icon: 'MedicineBoxFilled',hideInBreadcrumb: true, // 添加这行,可以去掉父元素带子级的面包屑path: '/hospital',routes: [// 这第一个对象的作用就是当点击父级菜单时,默认重定向到父级下的第一个子菜单页面{path: '/hospital',redirect: '/hospital/massage',},// 医生信息{path: '/hospital/massage',name: '医院信息',// icon:'SmileFilled',component: './HospitalMassage',layout: false,},// 医生管理{path: '/hospital/doctor',name: '医生管理',component: './DoctorOffice',layout: false,},// 排班管理{name: '医生排班管理',// icon: 'table',path: '/hospital/workforce',component: './workforce',layout: false,},// 标签管理{name: '标签管理',// icon: 'table',path: '/hospital/label',access: 'adminRouteFilter',component: './label',layout: false,},// 体检管理{name: '体检管理',// icon: 'table',path: '/hospital/physical',component: './physical',layout: false,},// 药品管理{name: '药品管理',// icon: 'table',path: '/hospital/drug',component: './drug',layout: false,},// 医院动态{name: '医院动态',// icon: 'table',path: '/hospital/dynamic',component: './dynamic',layout: false,},],},{path: '/',redirect: '/welcome',},{path: '*',layout: false,component: './404',},
];
二、动态路由实现步骤
1:配置路由访问权限(在routes.ts中给需要权限显示的路由添加:access)
// 科室管理{name: '科室管理',path: '/TableList',icon: 'DiffFilled',access: 'adminRouteFilter',component: './TableList',layout: true,},
2:权限控制(在access.ts中书写,需要根据自己的path进行修改)
// 动态路由控制
const adminRoutes = ['user', 'welcome', 'admin', 'list', 'TableList', 'hospital'];
const normalRoutes = ['user', 'list', 'TableList', 'hospital'];
const allUserRoutes = ['welcome'];export default function (initialState = {}) {// 取的当前账号const userInfo = JSON.parse(localStorage.getItem('user_account'));console.log('userInfo', userInfo);const isAdmin = userInfo === 'admin';const hasRoutes = isAdmin ? adminRoutes : normalRoutes;return {adminRouteFilter: () => isAdmin, // 只有管理员可访问normalRouteFilter: (route) => hasRoutes.includes(route.name), // initialState 中包含了的路由才有权限访问allUserRouteFilter: (route) => allUserRoutes.includes(route.name),};
}
分析权限控制代码:
1. 声明变量等于可以访问的菜单
const adminRoutes = ['user', 'welcome', 'admin', 'list', 'TableList', 'hospital'];
const normalRoutes = ['user', 'list', 'TableList', 'hospital'];
const allUserRoutes = ['welcome'];
2. 在登录页 存用户信息,用于对比
const userInfo = JSON.parse(localStorage.getItem('user_account'));console.log('userInfo', userInfo);
3. 在access.ts中取出来
// 取的当前账号const userInfo = JSON.parse(localStorage.getItem('user_account'));console.log('userInfo', userInfo);
4. 对比 可以访问的菜单
export default function (initialState = {}) {// 取的当前账号const userInfo = JSON.parse(localStorage.getItem('user_account'));console.log('userInfo', userInfo);const isAdmin = userInfo === 'admin';const hasRoutes = isAdmin ? adminRoutes : normalRoutes;return {adminRouteFilter: () => isAdmin, // 只有管理员可访问normalRouteFilter: (route) => hasRoutes.includes(route.name), // initialState 中包含了的路由才有权限访问allUserRouteFilter: (route) => allUserRoutes.includes(route.name),};
}