最近需求要给页面按钮加上权限
根据业务需求结合网上相关文章,有了以下权限代码。
整体思路是,用户登录后,拿到当前用户的按钮权限集合。再根据按钮权限codeKey去判断
。
一、定义权限按钮包裹组件,withRouter为了方便使用router
定义AuthWrap组件,让其返回一个组件,像这种高阶组件是参数为组件,返回值为新组件的函数。高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。
/** 按钮权限设计 */
import React, { FC, ReactElement } from 'react';
import { withRouter, RouteComponentProps } from 'react-router-dom';
import { Tooltip } from 'antd';
import './index.less';
import { getLocalUserPermissionsButton } from '@/utils/userToken';
/** 按钮置灰样式
.ant-btn-disabled {
color: rgba(0, 0, 0, 0.25) !important;
border-color: #DFE1E6 !important;
background: #f5f5f5 !important;
text-shadow: none !important;
box-shadow: none !important;
pointer-events: none; // 注意此行 解决点击穿透
}
**/
// 非路由组件可以通过withRouter高阶组件访问 History 对象的属性和进行匹配。withRouter将在渲染时向包装组件传递更新的 match、location 和 history 属性。
type AuthProps = {
authCode: string; // 权限codeKey
isShowTooltip?: boolean; // 无权限时,是否展示提示,默认true
children: any;
};
// 1.获取用户按钮权限集合,用户登录时,请求权限接口,拿到数据存入本地
const authBtnList = getLocalUserPermissionsButton();
// todo 渲染禁止按钮 无权限时,处理包裹的组件,移出click事件。为什么不加 disable属性?,会影响Tooltip的移入移出效果,配合css属性pointer-events: none;
const renderAuthBanButton: (children: any) => any = children => {
return React.Children.map(children, child => {
if (['boolean', 'undefined', 'string', 'number'].includes(typeof child) || child === null) {
return child;
}
if (child.props.children) {
return React.cloneElement(
child,
{
onClick: e => {
e.preventDefault();
return false;
},
className: 'ant-btn-disabled'
},
renderAuthBanButton(child.props.children)
);
}
return React.cloneElement(child, {
onClick: e => {
e.preventDefault();
return false;
},
className: 'ant-btn-disabled'
});
});
};
const AuthWrap: FC<AuthProps & RouteComponentProps> = props => {
const { authCode, isShowTooltip = true, children } = props;
let hasAuth = false;
if (authCode === undefined) {
return children;
} else {
// todo 2.自定义按钮权限逻辑校验
hasAuth = authBtnList.includes(authCode);
}
if (hasAuth) {
return children;
}
// TODO 无权限时,处理包裹的组件,移出click事件。
const authBanButton = renderAuthBanButton(children)
return <>{isShowTooltip ? <Tooltip title="无操作权限">{authBanButton}</Tooltip> : null}</>;
};
export default withRouter(AuthWrap);
二、页面使用
import AuthWrap from '@/components/AuthWrap';
# 直接包裹 里面可以有多级
<AuthWrap authCode={'role_create2'}>
<Button
type="primary"
className="action-btn-primary"
onClick={() => {
props.history.push(`/role/create`);
}}>
新建角色
</Button>
</AuthWrap>
三、效果
Hi ~ My code code code ...小记录