在使用 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),
};
}