我再也不敢说我会写前端 Button组件「实践」( 二 )

我再也不敢说我会写前端 Button组件「实践」

文章插图
 
咦 , 我们可以发现 , 好像它对 type 的定义更加符合我们的认知
<Button type="primary" /> // 蓝色<Button type="info" />// 淡蓝色<Button type="success" />// 绿色<Button type="warning" />// 橙色<Button type="danger" />// 红色Element UI我们再看一下 element UI 是如何定义的 , 跟 iView 差不多类似 , 也是符合我们认知的 。
我再也不敢说我会写前端 Button组件「实践」

文章插图
 
那么问题来了 , 我这个Button是否跟iView、Element UI一样 , 集成到 type , 还是类似于Ant Design一样 , 给个单独的属性?基于这个问题 , 在第一次评审 , 跟组里的小伙伴经过探讨 , 最终决定 , 单独给定一个属性叫做 color  , 由这个属性决定按钮的主题色 。而 type 仍表示它的一个“类型”
再来讨论一个叫做ghost的玩意 , 初始的时候 , 我是将其定义为一种“类型” , 但是后来 , 我发现 , 这个 ghost 它也是受主题色的影响 , 比如你红色时 , 幽灵按钮的文本颜色是红色 , 你绿色的时候 , 幽灵按钮的文本颜色是绿色 , 比如这个样子
我再也不敢说我会写前端 Button组件「实践」

文章插图
 
? 这里你可能要问了 , 不是有一个叫做 color 字段 , 用于修改主题色吗?
是的 , 但是有个问题我们要思考 , 什么是类型?举个  , 我们常问 , “你喜欢什么类型的电影” , 你可以说惊悚、动作、速度等类型的电影 , 但你说 , 我喜欢好看的电影 , 我们认真想一下 , “好看” , 它属于类型吗?不属于类型 , “好看”是这部电影的一个“属性” 。
当我们把这些属性定义好了之后 , 下边就没有我们担心的了 。我们来思考一下 , 如何去开发这个组件~
设计方案
我再也不敢说我会写前端 Button组件「实践」

文章插图
 
按照使用场景 , 最终我们可以定义出 , 如 Button、ButtonIcon、ButtonText , 再进一步的分析 , 会发现 , 这三种(甚至多种)类型的按钮 , 都会存在一些公共的状态属性 , 如 size、style、onClick、className 等 , 那么我们可以通过什么方式去实现呢?
? 本来想使用继承方式进行设计 , 但在 React 官网中 , 组合 VS 继承中 , 可看到 , React 推荐使用组合而非继承来实现组件间的代码重用 。React 推崇 HOC 和组合的方式 , React 希望组件是按照最小可用的思想来进行封装 , 在 OOP 原则中 , 这叫单一职责原则 。换句话说 , React 希望一个组件只专注于一件事 。
在这里使用继承是比较怪异的 , 比如你的代码写成这样
// 基类class BaseButton extends React.Component {}// 继承class Button extends BaseButton {}class ButtonIcon extends BaseButton {}class ButtonText extends BaseButton {}总感觉这里的继承是强行使用的 , 我们换成高阶组件的方式 , 会不会好一些?
// 高阶组件const BaseButtonHoc = WrApperComponent => {return class extends React.Component{return (<React.Fragment><WrapperComponent {...this.props} /></React.Fragment>)}}export default BaseButtonHoc;// 使用export default BaseButtonHoc(Button);export default BaseButtonHoc(ButtonIcon);export default BaseButtonHoc(ButtonText);嗯 , 看起来高阶组件方式更加使用 , 就用它吧 ~
? 注意 , ButtonGroup 只是一个包裹着 Button 的容器 , 这里不是 BaseButtonHoc衍生出来的类型 。
开发遇到的问题1. Button 样式优先级的定义为什么一开始我说要必须罗列好所有规则 , 因为中间只要有不符的 , 那么不好意思 , 你可能需要重写样式 。
拿 ButtonHOC 高阶组件来说 , 一开始我的设计就存在问题了 , 我们来看代码(我知道你们很不想看一坨代码 , 我尽量减少)


推荐阅读