组件库开发日志-Alert+Button | 青训营笔记

45 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第15天

Alert

需求分析

  • 有success、warning、danger3种类型的警告
  • 可以附加信息
  • 可以关闭窗口

开发难点

如何使窗口可关闭

使用一个状态close,值为true时表示窗口可关闭

使用三目运算符,当closetrue时返回null

如何附加信息

定义一个message属性,当属性有值时,返回一个p标签

可以用&&代替三目运算符

开发流程

定义接口

export interface AlertProps {
  title: string; // 提示文本
  message?: string;
  type?: 'success' | 'warning' | 'danger';
  closeable?: boolean; // 是否可关闭
}

创建组件

const Alert: React.FC<AlertProps> = ({
  title,
  message,
  type = 'success',
  closeable = true,
}) => {
  const [close, setClose] = useState(false)
  const classes = Classnames('alert', {
    [`alert-${type}`]: type,
  })
  const titleClasses = Classnames('alert-title', {
    'bold-title': message
  })
  const handleClose = () => setClose(true)
  return (
    close ? null : <div className={classes}>
      <span className={titleClasses}>{title}</span>
      {message && <p className="alert-message">{message}</p>}
      {closeable && <span className="alert-close" onClick={handleClose}>X</span>}
    </div>
  )
}


export default Alert;

Button

需求分析

  • buttonlink button两种类型,link button可跳转链接
  • 两种button都可以被禁用
  • 可以改变button大小和类型
  • 携带有原生的button属性

开发难点

如何同时携带两种button的原生属性

使用Partial<T>与TS的&&运算符,使两个标签能取到各自的原生属性

如何禁用button

使用disabled属性,并用样式来控制

开发流程

定义接口

export type ButtonSize = 'lg' | 'sm'
export type ButtonType = 'primary' | 'default' | 'danger' | 'link'
interface BaseButtonProps {
  className?: string;
  disabled?: boolean;
  size?: ButtonSize;
  btnType?: ButtonType;
  href?:string;
  children: React.ReactNode;
}
// 加入button和a标签的native attributes,
// 并使用Partial<T>使两个标签能取到各自的原生属性
export type ButtonProps = Partial<BaseButtonProps & 
  React.ButtonHTMLAttributes<HTMLElement> & 
  AnchorHTMLAttributes<HTMLElement>>

创建组件

if(btnType === 'link' && href){
  ret = (
    <a
      href={href}
      className={classnames}
      {...restProps}
      >{children}</a>
  )
}else{
  ret = (
    <button
      className={classnames}
      disabled={disabled}
      {...restProps}
      >{children}</button>
  )
}


return ret