PermissionButton 组件说明
描述
PermissionButton
组件用于根据用户角色和权限显示按钮,并在特定情况下启用加载效果。组件的显示、禁用和加载状态可以通过传入不同的属性来控制。
功能
- 权限控制:根据传入的
roles
(角色)和permissions
(权限)判断按钮是否显示和是否可点击。 - 加载效果:按钮可以显示加载状态,通常用于异步操作中。
- 按钮类型:支持
disabled
和hidden
两种按钮类型,分别对应禁用和隐藏按钮。
Props
属性名 | 类型 | 默认值 | 描述 |
---|---|---|---|
roles | Array<string> | [] | 用户的角色权限数组,用于检查按钮是否显示以及是否启用加载效果。如果为空,则不进行权限控制。 |
children | React.ReactNode | 必填 | 按钮的子元素内容,通常是按钮文本或图标。 |
onClick | Function | undefined | 按钮的点击事件处理函数。 |
btnType | string | 'disabled' | 按钮类型,支持 'disabled' (禁用按钮)和 'hidden' (隐藏按钮)。默认值为 'disabled' 。 |
permissions | Array<string> | [] | 用户的权限数组,检查用户是否有操作按钮的权限。 (取自 Redux) |
btnLoading | boolean | false | 控制按钮是否显示加载状态。如果传递此属性,优先控制加载状态。 |
restProps | Object | - | 传递给 Button 的其他属性,例如 style , className 等。 |
组件行为
-
权限控制:
- 如果
roles
和permissions
中的角色匹配,按钮将处于可点击状态。 - 如果
permissions
包含'unrestricted'
,则不进行权限控制,按钮始终可用。 - 如果没有传递
roles
或roles
为空数组,按钮将不进行权限控制。
- 如果
-
加载效果:
- 如果传递了
btnLoading
或roles
中包含'loading'
,按钮将显示加载指示器。 - 如果按钮处于加载状态,点击事件将被禁用,直到加载完成。
- 如果传递了
-
按钮类型:
'disabled'
:按钮禁用,点击时无法触发事件。'hidden'
:按钮根据权限是否匹配决定是否渲染。如果没有权限,则不渲染按钮。
示例
// 示例 1:没有权限控制,按钮永远可见
<PermissionButton onClick={() => console.log('点击按钮')}>
按钮
</PermissionButton>
// 示例 2:根据权限控制按钮显示和禁用
<PermissionButton roles={['admin']} permissions={['admin']} onClick={() => console.log('点击按钮')}>
管理员按钮
</PermissionButton>
// 示例 3:按钮加载状态
<PermissionButton roles={['admin']} btnLoading onClick={() => console.log('点击按钮')}>
加载按钮
</PermissionButton>
完整源码
import React, { useState } from 'react';
import { Button } from 'antd';
import { connect } from 'react-redux';
/**
* PermissionButton 组件根据用户权限显示按钮,并在特定条件下启用加载效果。
*
* @component
* @param {Object} props - 组件的属性。
* @param {Array<string>} [props.roles] - 用户角色权限数组,用于检查按钮是否显示及是否启用加载效果。如果数组为空,表示不进行权限控制。
* @param {React.ReactNode} props.children - 按钮的子元素内容。
* @param {Function} [props.onClick] - 按钮的点击事件处理函数。
* @param {Object} [props.restProps] - 传递给按钮的其他属性,例如 `style`, `className` 等。
* @param {string} [props.btnType='disabled'] - 按钮的类型,支持 'disabled'(禁用按钮)和 'hidden'(隐藏按钮)。默认为 'disabled'。
* @param {Array<string>} [props.permissions] - 用户的权限数组,用于检查用户是否有操作按钮的权限。如果不传递此参数,则不进行权限控制。(取redux的值)
* @param {boolean} [props.btnLoading=false] - 控制按钮是否在点击时显示加载状态。如果传递此属性,优先控制加载状态。
* @returns {React.ReactElement} 返回一个根据权限控制的按钮组件,支持加载效果。
*
* @example
* // 示例:没有权限控制,按钮永远可见
* <PermissionButton onClick={() => console.log('点击按钮')}>
* 按钮
* </PermissionButton>
*
* @example
* // 示例:根据权限控制按钮显示和禁用
* <PermissionButton roles={['admin']} permissions={['admin']} onClick={() => console.log('点击按钮')}>
* 管理员按钮
* </PermissionButton>
*
* @example
* // 示例: 按钮loading
* <PermissionButton roles={['admin']} btnLoading onClick={() => console.log('点击按钮')}>
* 加载按钮
* </PermissionButton>
*/
const PermissionButton = ({ roles = [], children, onClick, btnType = 'disabled', permissions = [], btnLoading, ...restProps }) => {
const [loading, setLoading] = useState(false);
// 权限控制逻辑
const hasUnrestrictedPermission = permissions.includes('unrestricted');
const hasLoadingRole = roles.includes('loading') || btnLoading;
// 如果没有传递 roles 或者 roles 为空数组,不进行权限控制
const isEnabled = (roles.length === 0 || hasUnrestrictedPermission || roles.some(role => permissions.includes(role)));
// 点击处理函数
const handleOnClick = async (e) => {
if (onClick) {
setLoading(true);
try {
await onClick(e);
} catch (error) {
// 错误处理
} finally {
setLoading(false);
}
}
};
// 如果权限数据尚未加载,显示加载指示器
if (!isEnabled && btnType === 'hidden') {
return null; // 没有权限时不渲染按钮
}
// 根据按钮类型渲染
if (btnType === 'disabled') {
return (
<Button
{...restProps}
loading={loading && hasLoadingRole}
onClick={handleOnClick}
disabled={!isEnabled || restProps.disabled}
>
{children}
</Button>
);
}
if (btnType === 'hidden') {
return isEnabled ? (
<Button
{...restProps}
loading={loading && hasLoadingRole}
onClick={handleOnClick}
>
{children}
</Button>
) : null; // 如果没有权限则不渲染按钮
}
return <></>; // 需要保证返回 null 的情况是预期的
};
const mapStateToProps = ({ account }) => ({
permissions: account.permissions,
});
export default connect(mapStateToProps)(PermissionButton);
总结
这个文档涵盖了组件的所有重要信息,包括其行为、如何配置、如何使用以及详细的参数说明。确保开发人员能够轻松理解并使用这个组件。