PermissionButton 组件说明

描述

PermissionButton 组件用于根据用户角色和权限显示按钮,并在特定情况下启用加载效果。组件的显示、禁用和加载状态可以通过传入不同的属性来控制。

功能

  • 权限控制:根据传入的 roles(角色)和 permissions(权限)判断按钮是否显示和是否可点击。
  • 加载效果:按钮可以显示加载状态,通常用于异步操作中。
  • 按钮类型:支持 disabledhidden 两种按钮类型,分别对应禁用和隐藏按钮。

Props

属性名类型默认值描述
rolesArray<string>[]用户的角色权限数组,用于检查按钮是否显示以及是否启用加载效果。如果为空,则不进行权限控制。
childrenReact.ReactNode必填按钮的子元素内容,通常是按钮文本或图标。
onClickFunctionundefined按钮的点击事件处理函数。
btnTypestring'disabled'按钮类型,支持 'disabled'(禁用按钮)和 'hidden'(隐藏按钮)。默认值为 'disabled'
permissionsArray<string>[]用户的权限数组,检查用户是否有操作按钮的权限。 (取自 Redux)
btnLoadingbooleanfalse控制按钮是否显示加载状态。如果传递此属性,优先控制加载状态。
restPropsObject-传递给 Button 的其他属性,例如 style, className 等。

组件行为

  1. 权限控制

    • 如果 rolespermissions 中的角色匹配,按钮将处于可点击状态。
    • 如果 permissions 包含 'unrestricted',则不进行权限控制,按钮始终可用。
    • 如果没有传递 rolesroles 为空数组,按钮将不进行权限控制。
  2. 加载效果

    • 如果传递了 btnLoadingroles 中包含 'loading',按钮将显示加载指示器。
    • 如果按钮处于加载状态,点击事件将被禁用,直到加载完成。
  3. 按钮类型

    • '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);

总结

这个文档涵盖了组件的所有重要信息,包括其行为、如何配置、如何使用以及详细的参数说明。确保开发人员能够轻松理解并使用这个组件。