看很多Issues都提出了菜单和路由权限动态获取的问题,基本都看了一遍,没发现好的路由权限解决问题。菜单权限动态获取可以通过更改BasicLayout.js的方法动态获取,但是路由无法更改,在mock中返回如下结构的menuData,其中的authority并不生效,只有在router.config.js中才生效。
[
{
"path": "/",
"redirect": "/dashboard/analysis",
"authority": ['admin', 'user'],
"exact": true,
},
{
"path": "/dashboard",
"name": "Dashboard",
"icon": "dashboard",
"children": [{
"path": "/dashboard/analysis",
"name": "分析页",
"authority": ["user"],
"exact": true,
}, {
"path": "/dashboard/monitor",
"name": "监控页",
"authority": ["user"],
"exact": true,
}, {
"path": "/dashboard/workplace",
"name": "工作台",
"exact": true,
}]
}
]
componentDidMount 时 增加查询当前菜单
dispatch({
type: 'global/getMenu',
payload: localStorage.getItem('antd-pro-authority'),
})
export default connect(({ global, setting }) => ({
menuData: global.menuData, // 增加当前菜单
collapsed: global.collapsed,
layout: setting.layout,
...setting,
}))(BasicLayout);
渲染时
render() {
const {
menuData, // 从props拿到当前menuData
navTheme,
layout: PropsLayout,
children,
location: { pathname },
} = this.props;
...
上面的改动可以实现菜单动态获取,路由获取时,不生效,即使不显示工作台菜单,却仍然可以通过http://localhost:8000/dashboard/workplace访问
/**
* 获取面包屑映射
* @param {Object} menuData 菜单配置
*/
getBreadcrumbNameMap() {
const routerMap = {};
const {menuData} = this.props
const mergeMenuAndRouter = data => {
data.forEach(menuItem => {
if (menuItem.children) {
mergeMenuAndRouter(menuItem.children);
}
// Reduce memory usage
routerMap[menuItem.path] = menuItem;
});
};
mergeMenuAndRouter(menuData); // 这里拿props里的menuData
return routerMap;
}
目前通过subscriptions监控路由暂时解决了路由访问时的问题,但不知道有没有问题
subscriptions: {
setup({ history }) {
// 如果没有key且不是首页则返回403,防止里直接输入localhost:8000/dashboard/workplace进行访问
if(!history.location.key && history.location.pathname !== '/'){
router.push('/exception/403');
}
// Subscribe history(url) change, trigger `load` action if pathname is `/`
return history.listen(({ pathname, search }) => {
if (typeof window.ga !== 'undefined') {
window.ga('send', 'pageview', pathname + search);
}
});
},
},
官方可否给出一个路由控制的实例,或者是大致思路方案,目前Issues有很多都未完结或者各自解决的
既然需求这么多,支持官方出个动态菜单的例子。
动态菜单的人真的很多,可以设置没有在菜单中显示的路由为 403
动态菜单的人真的很多,可以设置没有在菜单中显示的路由为 403
想在每个路由进入前判断是否在菜单中,不在就返回403,目前在BasicLayout里的componentDidUpdate时做了一下判断,感觉不是很合理,有其它的方法么
重写 一下权限路由,没有权限就给返回403好了,现在为 false 的时候默认是放过的。
重写 一下权限路由,没有权限就给返回403好了,现在为 false 的时候默认是放过的。
是说Authorized里的这部分代码么 这个感觉实现有些复杂 一定要在每个菜单里添加authority 数组节点
const checkPermissions = (authority, currentAuthority, target, Exception) => {
// 没有判定权限.默认查看所有
// Retirement authority, return target;
if (!authority) {
return target;
}
...
}
重写 一下权限路由,没有权限就给返回403好了,现在为 false 的时候默认是放过的。
是说Authorized里的这部分代码么 这个感觉实现有些复杂 一定要在每个菜单里添加
authority数组节点
js const checkPermissions = (authority, currentAuthority, target, Exception) => { // 没有判定权限.默认查看所有 // Retirement authority, return target; if (!authority) { return target; } ... }按照你的写法能够实现,但是页面刷新完后选择的菜单没有激活(没有被选择的颜色背景)
动态菜单的人真的很多,可以设置没有在菜单中显示的路由为403
想在每个路由进入前判断是否在菜单中,不在就返回403,目前在将BasicLayout里的componentDidUpdate时做了一下判断,感觉不是很合理,有其它的方法么
问一下,你这边最后是如何解决这个问题的,我现在也遇到一样的问题,没有找到好的解决方案。
在 UmiJS3 里面的运行时配置中动态修改路由的 authority 字段,就可以满足你需求
Most helpful comment
既然需求这么多,支持官方出个动态菜单的例子。