需求:
给系统所有按钮加上权限控制,有权限则显示,没有则隐藏。
(顺提一下为什么不用disabled:因为本身的业务逻辑就有判断是否disbled,加权限是系统已经做了很久之后加的需求,如再用disabled会让业务逻辑有些混乱)
项目背景
项目为基于react的一个后台管理系统,使用umi+dva+antd的整一套系统性架构
前期准备
-
通过后端接口返回权限数据如下:
数据截图
- 系统登录的同时获取权限数据,并保存在sessionStorage中(下面省略请求数据的代码)
const STORE_MENUS = 'antd-menus';
updateMenus(state, action) {
const { payload } = action;
sessionStorage.setItem(STORE_MENUS, JSON.stringify(payload));
return {
...state,
};
},
重点来了 -- 解决历程
方案一:使用高阶组件加工一次原本的按钮
import React, { Component } from 'react';
const WrapAuth = ComposedComponent => class WrapComponent extends Component {
// 判断是否有权限
handleAuth = (id) => {
const menujson = sessionStorage.getItem('antd-menus');
if (menujson != null) {
const menuData = JSON.parse(menujson);
const { code, data } = menuData;
if (code === 200 && data) {
const { buttons } = data;
return buttons.includes(id);
}
}
return false;
}
render() {
const { authority } = this.props;
if (this.handleAuth(authority)) {
return <ComposedComponent {...this.props} />;
}
return null;
}
};
export default WrapAuth;
使用高阶组件,这里出现了一个问题,就是我们的按钮有可能使用了 antd 的 Button
组件,也有可能是 Link
,那每次要用 WrapAuth
时就需要为不同的组件各自加工一次,如:
import WrapAuth from '@/components/WrapAuth';
const WrapButton = WrapAuth(Button);
const WrapLink = WrapAuth(Link);
因为这个问题,故思考了另一种方案
方案二:写个函数式组件包装原来的按钮控制其显示与否
const WrapAuth = (props) => {
const handleAuth = (id) => {
const menujson = sessionStorage.getItem('antd-menus');
if (menujson != null) {
const menuData = JSON.parse(menujson);
const { code, data } = menuData;
if (code === 200 && data) {
const { buttons } = data;
return buttons.includes(id);
}
}
return false;
}
const { authority, children } = props;
return handleAuth(authority) ? {...children} : null;
};
export default WrapAuth;
如何使用
import WrapAuth from '@/components/WrapAuth';
<WrapAuth authority="906871085780005">
<Button icon="plus" type="primary" onClick={this.handleAdd}>
新建
</Button>
</WrapAuth>
<WrapAuth authority="906871085840005">
<>
<a onClick={e => this.handleEdit(e, record.exhibitionId)}>编辑</a>
<Divider type="vertical" />
</>
</WrapAuth>
总结
- 通过后端接口枚举权限id的方式虽然解决了权限控制问题,但是总感觉这种方式太粗暴,希望以后能学到更好的方式
- 高阶组件就是个函数,它并不是一个组件,虽然用起来感觉高大上,但不是所有问题都用它解决,就以上的场景来看,简简单单写个函数式组件更好
- 写函数式组件时,当所写组件转译之后并没有用到
react.createElement
时,可以不引入React
网友评论