文章目录
前言
Ant Design Pro是蚂蚁金服团队出品的一款前端框架,安装完毕后可以看到菜单和路由是静态渲染的,在实际的开发过程中,经常需要根据用户名或者权限生成不同的菜单,下面介绍一下具体的实现过程。
开发环境:
- 后端:Spring 4.2.1
- 前端:Ant Design Pro V2
- jdk:1.8
实现效果
使用admin用户登录时,显示管理员菜单项,使用其它用户登录时,显示普通用户菜单项
前端实现过程
官网文档
在官网中https://v2-pro.ant.design/docs/router-and-nav-cn,有这样一句话:
只需在 models/menu 中发起 http 请求,menuData 是一个 json 数组。只需服务器返回类似格式的 json 即可。
[
{
path: '/dashboard',
name: 'dashboard',
icon: 'dashboard',
children: [
{
path: '/dashboard/analysis',
name: 'analysis',
exact: true,
},
{
path: '/dashboard/monitor',
name: 'monitor',
exact: true,
},
{
path: '/dashboard/workplace',
name: 'workplace',
exact: true,
},
],
}
...
]
BasicLayout组件中调用model/menu.js
登陆成功后,首先在layouts/BasicLayout.js中通过dva异步调用model/menu.js中的方法获取菜单
class BasicLayout extends React.Component {
componentDidMount () {
const {
dispatch,
route: {
routes, path, authority },
} = this.props;
dispatch({
type: 'user/fetchCurrent',
});
dispatch({
type: 'setting/getSetting',
});
dispatch({
type: 'menu/getMenuData', // 异步调用model/menu.js中获取菜单的方法
payload: {
routes, path, authority },
});
}
}
model/menu.js中引入service
在model/menu.js中定义异步方法
effects: {
* getMenuData ({
payload }, {
call, put }) {
const {
routes, authority, path } = payload;
const originalMenuData = memoizeOneFormatter(routes, authority, path);
// const menuData = filterMenuData(originalMenuData); //Mock方法
const menuData = yield call(queryMenus, getUser()); // 后台根据用户名获取自定义菜单
const breadcrumbNameMap = memoizeOneGetBreadcrumbNameMap(originalMenuData);
yield put({
type: 'save',
payload: {
menuData, breadcrumbNameMap, routerData: routes },
});
},
},
reducers: {
save (state, action) {
return {
//更新State
...state,
...action.payload,
};
},
},
service中定义后端API
创建services/menu.js文件,定义后端API
import request from '@/utils/request';
// eslint-disable-next-line import/prefer-default-export
export async function queryMenus(user) {
return request(`/api/accounts/${
user}/menus`);
}
后端实现过程
定义菜单类
在这个过程中用到了类的递归,调试过程中发现使用@Data注解给children属性赋值时会报错,所以直接在IDEA中右键-Generate-Getter/Setter-全部选中,生成Setter/Getter方法。
public class MenuData {
private String path;
private String name;
private String icon;
private Boolean exact;
private Set<MenuData> children = new HashSet<>();
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public Boolean getExact() {
return exact;
}
public void setExact(Boolean exact) {
this.exact = exact;
}
public Set<MenuData> getChildren() {
return children;
}
public void setChildren(Set<MenuData> children) {
this.children = children;
}
}
定义控制器
定义MenuController.java
@RequestMapping(value = "/accounts/{user}/menus", method = RequestMethod.GET)
public ResponseEntity<List<MenuData>> getMenuData(@PathVariable("user") String user) {
List<MenuData> menusDataList = new ArrayList<>();
if (user.equals("admin")) {
//父级菜单
MenuData parent = new MenuData();
parent.setExact(true);
parent.setIcon("dashboard");
parent.setName("管理员-控制面板");
parent.setPath("/dashboard");
parent.setChildren(new HashSet<>());
//子级菜单
MenuData child1 = new MenuData();
child1.setExact(true);
child1.setIcon("analysis");
child1.setName("管理员-分析");
child1.setPath("/dashboard/analysis");
child1.setChildren(new HashSet<>());
MenuData child2 = new MenuData();
child2.setExact(true);
child2.setIcon("monitor");
child2.setName("管理员-监控");
child2.setPath("/dashboard/monitor");
child2.setChildren(new HashSet<>());
parent.getChildren().add(child1);
parent.getChildren().add(child2);
menusDataList.add(parent);
} else {
//父级菜单
MenuData parent = new MenuData();
parent.setExact(true);
parent.setIcon("dashboard");
parent.setName("普通用户-控制面板");
parent.setPath("/dashboard");
parent.setChildren(new HashSet<>());
//子级菜单
MenuData child1 = new MenuData();
child1.setExact(true);
child1.setIcon("analysis");
child1.setName("普通用户-分析");
child1.setPath("/dashboard/analysis");
child1.setChildren(new HashSet<>());
MenuData child2 = new MenuData();
child2.setExact(true);
child2.setIcon("monitor");
child2.setName("普通用户-监控");
child2.setPath("/dashboard/monitor");
child2.setChildren(new HashSet<>());
parent.getChildren().add(child1);
parent.getChildren().add(child2);
menusDataList.add(parent);
}
return new ResponseEntity<>(menusDataList, HttpStatus.OK);
}
效果验证
后端监测:
前端监测:
使用admin用户登录:
使用user用户登录: