我现在想在后台校验权限然后在pro里显示指定的菜单,这个要怎么做呢?
文档里需要提及一下,相似的问题略多。
https://github.com/ant-design/ant-design-pro/commit/b75f71dbab16dfb165265a1a5ae394bc7c94f675
看这个提交。等这个被 merge 进 v2 就开始写文档好了
新手看这个还真是有点费劲呢
clone 下来看效果吧。
就比较简单了。 top nav 分支
好的
https://github.com/ant-design/ant-design-pro/commit/b75f71dbab16dfb165265a1a5ae394bc7c94f675
这个提交只是增加了LoadingPage在BasicLayout前处理菜单信息
@zhaxingaz 如果你要后台动态传递,你需要知道两个事:
1、只传递菜单,路由需要配合,要不要路由一起
2、目前antdp还在更新中。。。这些改动的兼容你得自己来
如果没问题,我建议你在目前版本的BasicLayout上connect一个menu的model,绑定传递给SiderMenu绑定就好,menu中权限需要传递绑定到路由中去,这个需要你自己调整
@mitoriko 你说的我不是很明白,我现在主要想实现的功能是:
1.登陆时去后台校验,返回用户权限currentAuthority
2.登陆成功后,进入主页,左侧菜单栏中只显示当前登陆用户有操作权限的菜单项
我现在的理解是当前这个版本需要将有权限的用户写死到menu.js里,是不是这样?
另外还有个问题就是我在浏览器里直接访问一个页面时需要去后台校验是否登陆,我不清楚在哪里去发这个校验请求?
@mitoriko 我之前对js比较熟悉,现在antdp这种代码风格使我无法去跟踪详细的代码执行过程,很头疼,有什么方法吗
用 redux devtool 和控制台就可以了
@zhaxingaz
1、登录login接口你可以把auth从后台返回来,官方例子写在localstorage里,你要是换地方需要自己处理getAuthority。
2、菜单信息可以不写死在menu.js里,你新创建一个model,在BasicLayout中传递connect,SiderMenu数据绑定这个model的状态(不要忘记formatter),然后你要处理路由部分(其实菜单不是重点,路由才是大坑),router.js入口权限、common\router.js里的菜单与路由权限绑定、SiderMenu权限验证等地方都要改。
3、你可以参考一下Authorized组件的demo,可以考虑用function验证,或者你切换菜单时候后台撸一遍也行
@mitoriko 我想找到菜单项的单击事件绑定位置dubug一下应该在哪去找
我现在不想做太多复杂性的修改,我想在菜单项切换时给后台发个请求校验一下
https://ant.design/components/menu-cn/
@zhaxingaz 需要加强一下基本功了
你可以参照文档找到
菜单项的单击事件
但是没有意义,因为那个菜单是Link,最终还是路由来解决问题
你不如在AuthorizedRoute里把authority={authority}改成方法验证
order: 2
title:
zh-CN: 使用方法作为参数
Use Function as a parameter
import RenderAuthorized from 'ant-design-pro/lib/Authorized';
import { Alert } from 'antd';
const Authorized = RenderAuthorized('user');
const noMatch = <Alert message="No permission." type="error" showIcon />;
const havePermission = () => {
return false;
};
ReactDOM.render(
<Authorized authority={havePermission} noMatch={noMatch}>
<Alert
message="Use Function as a parameter passed!"
type="success"
showIcon
/>
</Authorized>,
mountNode,
);
嗯嗯
@mitoriko 改成方法验证的作用是什么呢?我不太明白,是在这个方法里去后台验证吗?
@mitoriko 我现在修改了master版本为方法验证,报错了:
←→2 of 2 errors on the page
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
? 19 stack frames were collapsed.
(anonymous function)
src/index.js:81
78 | })(); // 5. Start
79 |
80 |
81 | app.start('#root');
82 | FastClick.attach(document.body);
83 | export default app._store; // eslint-disable-line
84 |
View compiled
? 6 stack frames were collapsed.
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser’s developer console to further inspect this error.
后来我又在top_nav版本上修改了,没有报错,效果是方法返回false时直接调到登陆页面,返回true时可以访问主页及交易页面
我现在是不是应该使用top_nav版本呢?
@zhaxingaz top_nav 最近将会合并到 v2 分支。
你这个错误是因为componentDidUpdate 中调用 setSate 造成死循环了。
你应该排查一下你的代码。
top_nav 是未来的代码会经常变动
好的
我在AuthorizedRoute里添加了componentWillUnmount(),代码如下:
componentWillUnmount() {
const { dispatch } = this.props;
dispatch({
type: 'login/validate',
});
}
同时,我在login models里添加了validate并打印了日志,这样是可以调用的,而当我重新写了一个models permission.js时,下面的写法调不到permission.js里的validate,代码如下:
componentWillUnmount() {
const { dispatch } = this.props;
dispatch({
type: 'permission/validate',
});
}
几乎是同样的写法,却出现了两个结果,求解惑
怀疑你没把model引进来
这个问题,你可以看之前也有提交过相同的问题,先用注解的方法,我这边也是用这个方法的

摸索了好多天,现在终于会用了,还需要继续研究
期待V2!!!
@mitoriko 菜单的展示用 @LKCheng 说的方法很好实现,现在的难点是Router这块与菜单数据的耦合,不知道该如何处理Router数MenuData的问题,你有推荐的方式么?
高阶组件的方式很难做到异步获取的menu 数据传入路由,所以换个思路,应该以路由为出发点,下面是我的实现,如有不当,请指正
class RouterConfig extends React.Component<any, any> {
componentDidMount() {
authService.getAuthMenus().then(data => this.setState({menus: data}));
}
render() {
if (this.state && this.state.menus && this.state.menus.length) {
const menus = this.state.menus;
const { history, app }: any = this.props;
const routerConfig = getRouterConfig(app, menus);
const UserLayout = routerConfig['/user'].component;
const BasicLayout = routerConfig['/'].component;
// 存入redux,用于后续权限判断等
app._store.dispatch({
type: 'global/saveMenus',
payload: menus
});
return (
<LocaleProvider locale={zhCN}>
<ConnectedRouter history={history}>
<Switch>
<Route
path="/user"
component={UserLayout}
/>
<AuthorizedRoute
path="/"
render={props => <BasicLayout {...props} menus={menus} />}
authority={hasPermission()}
redirectPath="/user/login"
/>
</Switch>
</ConnectedRouter>
</LocaleProvider>
);
}
return <Spin size="large" className={styles.globalSpin} />;
}
}
export default RouterConfig;
@quaider 您好 您的动态菜单结合路由实现了吗?可以指导一下吗?
The same problem
@290352095 @chengnuo 这个可以参考 https://github.com/quaider/dynamic-menu-antdp
主要是 /common/router.ts 将获取route data时机改变了, /models/global.ts获取菜单成功后,计算RouteData,然后都存入redux
menu和RouteData由高阶组件传入BasicLayout
@quaider 谢谢,确实应该改变一下获取时机 我直接在登录后跳转前,获取到了菜单数据,这样就不会错了
我是直接把common里面的menu不用了,接口拿来后自己本地处理一下就丢给BasicLaout组件,具体逻辑放在了BasicLaout里面
@ mitoriko
菜单栏数据异步获取后
common\router.js 中 routerData里面的数据
routerData这个里面 key对应的value值
都是undefined了诶

@quaider 具体是怎么改变/common/router.ts 将获取route data的时机的呢
Most helpful comment
https://github.com/ant-design/ant-design-pro/commit/b75f71dbab16dfb165265a1a5ae394bc7c94f675
看这个提交。等这个被 merge 进 v2 就开始写文档好了