services/api.jsexport async function getMenu() {
return request('/api/*********/GetMenu', {
method: 'POST'
});
}
models/menu.js引入
import { getMenu } from '@/services/api';
effects: {
*getMenuData({ payload }, {call, put }) {
const response = yield call(getMenu);//这里调用接口
// const { routes, authority } = payload; //这里是原代码
const menuData = filterMenuData(memoizeOneFormatter(response.data.routes, response.data.authority));
const breadcrumbNameMap = memoizeOneGetBreadcrumbNameMap(menuData);
yield put({
type: 'save',
payload: { menuData, breadcrumbNameMap },
});
},
},
注:个人建议角色不要在客户端Local Storage中,因为ant design pro运行在前端,怕被篡改角色,即使不会暴露敏感功能,如果使用了JWT,应该把安全性和角色问题放到服务端处理。小弟最近才上手ant不知道理解得对不对,只是把这几天的研究成果放到这来希望对入门的新手有用。望各位大神指点。
为啥子,我感觉v1版本的菜单更好理解,后端返回还更好控制。v2的还是看的有的多参
先格式化一下文章?
v1版本之前models在router文件中可以挂载,v2是 在 umi 中 models 文件夹中的 dva model 会被自动挂载,要按照他文件下的格式嘛
@LKCheng 我研究完写的这个代码只能获取服务端menu,因为自动挂载了router.config.js,角色也在其中,导致后面添加了新页面时访问跳转到403。还需要处理一下Authorized。
@lattemj 对于第三步中的数据,我在mock中写了假数据、数据是copy的router.config.js中的数据。但是菜单显示不出来、这边有没有现成的json格式么。
@jinhai123 router.config.js中的数据不能全用,你要知道哪一部份才是菜单的路由设置,你也可以查看源码解析的哪一部份:
```
{
path: '/dashboard',
name: 'dashboard',
icon: 'dashboard',
routes: [
{
path: '/dashboard/analysis',
name: 'analysis',
component: './Dashboard/Analysis',
},
{
path: '/dashboard/monitor',
name: 'monitor',
component: './Dashboard/Monitor',
},
{
path: '/dashboard/workplace',
name: 'workplace',
component: './Dashboard/Workplace',
},
],
},
BasicLayout.js 修改部分
render() {
const {
navTheme,
layout: PropsLayout,
children,
location: { pathname },
isMobile,
menuData,
breadcrumbNameMap,
route: { routes },
fixedHeader,
} = this.props;
const isTop = PropsLayout === 'topmenu';
const routerConfig = this.getRouterAuthority(pathname, routes);
//改成
const routerConfig = this.getDymincRouterAuthority(pathname, routes);
getRouterAuthority = (pathname, routeData) => {
let routeAuthority = ['noAuthority'];
const getAuthority = (key, routes) => {
routes.map(route => {
if (route.path && pathToRegexp(route.path).test(key)) {
routeAuthority = route.authority;
} else if (route.routes) {
routeAuthority = getAuthority(key, route.routes);
}
return route;
});
return routeAuthority;
};
return getAuthority(pathname, routeData);
};
/**动态菜单权限判断**/
getDymincRouterAuthority = (pathname, routeData) => {
let routeAuthority = ['noAuthority'];
const getAuthority = (key, routes) => {
routes.map(route => {
if (route.path && pathToRegexp(route.path).test(key)) {
routeAuthority = route.authority;
} else if (route.children) {
routeAuthority = getAuthority(key, route.children);
}
return route;
});
return routeAuthority;
};
return getAuthority(pathname, routeData);
};
{
path: '/goods',
name: 'goods',
icon: 'shop',
authority: ['admin', 'user'],
routes: [
{
path: '/goods/success',
name: 'create',
component: './Goods/Success',
},
{ path: '/goods/list', name: 'list', component: './Goods/Error' },
{ path: '/goods/category', name: 'category', component: './Goods/Category' },
{ path: '/goods/fail', name: 'edit', component: './Goods/Fail' },
]
},
@lattemj 我也是你这种方案实现的,但是新增页面一直报这个错误

@denghp path和component需要在router.config.js中全部配置好,具体的菜单分级后端拼接,注意的是后端返回的页面在router.config.js中必须是存在的。这个暂时不支持动态挂载。个人理解就是假的动态菜单,控制显示而已。如果你有链接还是可以通过敲链接进,如果权限够的情况。
@denghp path和component需要在router.config.js中全部配置好,具体的菜单分级后端拼接,注意的是后端返回的页面在router.config.js中必须是存在的。这个暂时不支持动态挂载。个人理解就是假的动态菜单,控制显示而已。如果你有链接还是可以通过敲链接进,如果权限够的情况。
嗯,确实是需要在router.config.js中配置,那这样就失去了动态从服务端获取菜单的意义了,毕竟服务端是管理菜单的分级和菜单角色。
我前端时间使用vue-admin-template脚手架实现动态获取菜单是思路:
1、服务端获取菜单及对应角色
2、客户端这不保存component的map
export const routerComponents = {
Layout: {
component: Layout
},
NotFound: {
component: () => import('@/views/errorPage/404')
},
Dashboard: {
component: () => import('@/views/dashboard/index')
},
Administrator: {
component: () => import('@/views/auth/users/index')
},
}
3、从服务端获取菜单递归绑定上对应的compoent
function filterConvertAsyncRouter(routes) {
const res = []
routes.forEach(route => {
const tmp = { ...route }
// 判断是否Layout
if (route.isLayout !== undefined && route.isLayout === true) {
tmp.component = routerComponents['Layout'].component
} else {
const routerComponent = routerComponents[route.name]
if (routerComponent !== undefined) {
tmp.component = routerComponent.component
} else {
tmp.component = routerComponents['NotFound'].component
}
}
if (tmp.children) {
tmp.children = filterConvertAsyncRouter(tmp.children)
}
res.push(tmp)
})
return res
}
不知道ant-design-pro能否采用这种思路实现?我看了好久也没找到router.config.js 实例化的地方
@denghp Vue支持动态router这我知道,我也做过类似的。但是这个是react的,react和angular应该都不支持动态加载路由的,这是本身机制问题,改变不了。而且人家在文档中已经给出了,不支持动态挂载router
@denghp Vue支持动态router这我知道,我也做过类似的。但是这个是react的,react和angular应该都不支持动态加载路由的,这是本身机制问题,改变不了。而且人家在文档中已经给出了,不支持动态挂载router
我是刚学react, 还是小白
@denghp Vue支持动态router这我知道,我也做过类似的。但是这个是react的,react和angular应该都不支持动态加载路由的,这是本身机制问题,改变不了。而且人家在文档中已经给出了,不支持动态挂载router
我是刚学react, 还是小白
我比你还白,,我也是这几天才知道。不知道熬了多长时间,恶补知识。前端根本一窍不通。全凭不要脸的精神一顿问。。。
@denghp Vue支持动态router这我知道,我也做过类似的。但是这个是react的,react和angular应该都不支持动态加载路由的,这是本身机制问题,改变不了。而且人家在文档中已经给出了,不支持动态挂载router
我是刚学react, 还是小白
我比你还白,,我也是这几天才知道。不知道熬了多长时间,恶补知识。前端根本一窍不通。全凭不要脸的精神一顿问。。。
互相学习,我一直做后台开发的,最近学的前端,我们的思路一致,都是通过后台JWT控制权限,前端动态加载
新手求助~请问用了上面的方式实现了动态菜单,authority准入权限怎么才能实现动态配置喃?谢谢~
新手求助请问用了上面的方式实现了动态菜单,authority准入权限怎么才能实现动态配置喃?谢谢
权限不推荐前端完全控制,用jwt好一点吧 。我也正在研究
大神们,有人做过动态菜单的国际化吗?可以和我说一下实现思路吗?