组件库起航-基本Button组件

2020-07-16  本文已影响0人  再见地平线_e930

前言:在我们的日常开发包括日常开发中,经常与button打交道,在一个组件库中,Button组件也是最易开发的一个。

仓库地址:

https://gitee.com/cquptzsn/fun-ui

需求分析:

一、首先,定义按钮的一些属性:

ButtonType-按钮类型

使用枚举:

export enum ButtonType {

    Primary = 'primary',

    Default = 'default',

    Danger = 'danger',

    Link = 'link'

}

ButtonSize-按钮大小:

export enum ButtonSize {

    Large = 'lg',

    Small = 'sm'

}

二、通过classNames给不同的属性设置不同的类名从而设置不同样式

const classes = classNames('btn', className, {

        [`btn-${btnType}`]: btnType,

        [`btn-${size}`]: size,

        'disabled': (btnType === ButtonType.Link) && disabled

    })

*三、为了使我们封装的Button 组件能有原生 button 和 a标签 的属性,需要把我们自定义的props 和 button , a 原生的属性结合

自定义的属性

使用 typescript 获取原生属性提示和自定义属性结合:

button: type NativeButtonProps = BaseButtonProps & React.ButtonHTMLAttributes

a:             type AnchorButtonProps = BaseButtonProps & React.AnchorHTMLAttributes

将这两个属性结合并设置可选, 这里使用 typescript 的 Partial<>

export type ButtonProps = Partial<NativeButtonProps & AnchorButtonProps> //使用 Partial<> 使两种属性可选

通过以上步骤,我们封装的 Button 组件能够获取原生 button 和 a 的相关属性

四、不同标签设置返回不同内容

五、使用

要先导入

之后,我们给不同的类名设置不同样式即可

总代码:

import React from 'react';

import classNames from 'classnames'

export enum ButtonSize {

    Large = 'lg',

    Small = 'sm'

}

export enum ButtonType {

    Primary = 'primary',

    Default = 'default',

    Danger = 'danger',

    Link = 'link'

}

interface BaseButtonProps {

    className?: string;

    disabled?: boolean;

    size?: ButtonSize;

    btnType?: ButtonType;

    children: React.ReactNode;

    href?: string;    

}

type NativeButtonProps = BaseButtonProps & React.ButtonHTMLAttributes<HTMLButtonElement> // 使用 交叉类型(&) 获得我们自己定义的属性和原生 button 的属性

type AnchorButtonProps = BaseButtonProps & React.AnchorHTMLAttributes<HTMLAnchorElement> // 使用 交叉类型(&) 获得我们自己定义的属性和原生 a标签 的属性

export type ButtonProps = Partial<NativeButtonProps & AnchorButtonProps> //使用 Partial<> 使两种属性可选

const Button: React.FC<ButtonProps> = (props) => {

    const { 

        disabled,

        className, 

        size,

        btnType,

        children,

        href,

        ...restProps  

    } = props;

    const classes = classNames('btn', className, {

        [`btn-${btnType}`]: btnType,

        [`btn-${size}`]: size,

        'disabled': (btnType === ButtonType.Link) && disabled  // 只有 a 标签才有 disabled 类名,button没有

    })

    if(btnType === ButtonType.Link && href) {

        return (

            <a 

            className={classes}

            href={href}

            {...restProps}

            >

                {children}

            </a>

        )

    } else {

        return (

            <button 

            className={classes}

            disabled={disabled} // button元素默认有disabled属性,所以即便没给他设置样式也会和普通button有一定区别

            {...restProps}

            >

                {children}

            </button>

        )

    }

}

Button.defaultProps = {

    disabled: false,

    btnType: ButtonType.Default

}

export default Button;

最后: 这里我只做了一些基本的类型,感兴趣可以自己再添加,样式文件我就不发出来了

上一篇 下一篇

猜你喜欢

热点阅读