Ant-Design源码分析——Result

2021SC@SDUSC

用于反馈一系列操作任务的处理结果。

首先是导入相应的模块

import * as React from react;
import classNames from classnames;
import CheckCircleFilled from @ant-design/icons/CheckCircleFilled;
import CloseCircleFilled from @ant-design/icons/CloseCircleFilled;
import ExclamationCircleFilled from @ant-design/icons/ExclamationCircleFilled;
import WarningFilled from @ant-design/icons/WarningFilled;

import { ConfigContext } from ../config-provider;
import devWarning from ../_util/devWarning;

import noFound from ./noFound;
import serverError from ./serverError;
import unauthorized from ./unauthorized;

四种Icon

export const IconMap = {
  success: CheckCircleFilled,
  error: CloseCircleFilled,
  info: ExclamationCircleFilled,
  warning: WarningFilled,
};

success:

error:

info:

warning:

三种异常

export const ExceptionMap = {
  404: noFound,
  500: serverError,
  403: unauthorized,
};
export interface ResultType extends React.FC<ResultProps> {
  PRESENTED_IMAGE_404: React.ReactNode;
  PRESENTED_IMAGE_403: React.ReactNode;
  PRESENTED_IMAGE_500: React.ReactNode;
}
Result.PRESENTED_IMAGE_403 = ExceptionMap[403];
Result.PRESENTED_IMAGE_404 = ExceptionMap[404];
Result.PRESENTED_IMAGE_500 = ExceptionMap[500];

404:

500:

403:

定义result接口

export interface ResultProps {
  // result的图像
  icon?: React.ReactNode;
  // result的状态
  status?: ResultStatusType;
  // 主标题
  title?: React.ReactNode;
  // 副标题
  subTitle?: React.ReactNode;
  // 操作区(可以添加button等)
  extra?: React.ReactNode;
  // 前缀信息,用于区分
  prefixCls?: string;
  className?: string;
  style?: React.CSSProperties;
}
// ExceptionImageMap keys
const ExceptionStatus = Object.keys(ExceptionMap);

根据需要的的状态与icon返回result组件

const renderIcon = (prefixCls: string, { status, icon }: ResultProps) => {
  const className = classNames(`${prefixCls}-icon`);

  devWarning(
    !(typeof icon === string && icon.length > 2),
    Result,
    ``icon` is using ReactNode instead of string naming in v4. Please check `${icon}` at https://ant.design/components/icon`,
  );

  // 查询是否包含该状态
  if (ExceptionStatus.includes(`${status}`)) {
    const SVGComponent = ExceptionMap[status as ExceptionStatusType];
    return (
      <div className={`${className} ${prefixCls}-image`}>
        <SVGComponent />
      </div>
    );
  }
  
  // 否则另行创建
  const iconNode = React.createElement(
    IconMap[status as Exclude<ResultStatusType, ExceptionStatusType>],
  );

  return <div className={className}>{icon || iconNode}</div>;
};

最后通过result的属性返回result组件

const Result: ResultType = ({
  prefixCls: customizePrefixCls,
  className: customizeClassName,
  subTitle,
  title,
  style,
  children,
  status = info,
  icon,
  extra,
}) => {
  const { getPrefixCls, direction } = React.useContext(ConfigContext);

  const prefixCls = getPrefixCls(result, customizePrefixCls);
  const className = classNames(prefixCls, `${prefixCls}-${status}`, customizeClassName, {
    [`${prefixCls}-rtl`]: direction === rtl,
  });
  return (
    <div className={className} style={style}>
      {renderIcon(prefixCls, { status, icon })}
      <div className={`${prefixCls}-title`}>{title}</div>
      {subTitle && <div className={`${prefixCls}-subtitle`}>{subTitle}</div>}
      {renderExtra(prefixCls, { extra })}
      {children && <div className={`${prefixCls}-content`}>{children}</div>}
    </div>
  );
};
经验分享 程序员 微信小程序 职场和发展