![f7679590723e81d580ff236f495033e9.png](https://i-blog.csdnimg.cn/blog_migrate/b4434f77cec6cb01a28b1d28c43633c5.jpeg)
前言
本文是笔者写组件设计的第五篇文章,之所以会写组件设计相关的文章,是因为作为一名前端优秀的前端工程师,面对各种繁琐而重复的工作,我们不应该按部就班的去"辛勤劳动",而是要根据已有前端的开发经验,总结出一套自己的高效开发的方法.作为数据驱动的领导者react/vue等MVVM框架的出现,帮我们减少了工作中大量的冗余代码, 一切皆组件的思想深得人心.所以, 为了让工程师们有更多的时间去考虑业务和产品迭代,我们不得不掌握高质量组件设计的思路和方法.所以笔者将花时间去总结各种业务场景下的组件的设计思路和方法,并用原生框架的语法去实现各种常用组件的开发,希望等让前端新手或者有一定工作经验的朋友能有所收获.
今天主要带大家一起实现一个Tag组件和Empty(空状态)组件,在介绍组件设计之前,先给大家介绍一个免费开源的图标库icomoon,
![df99b7938c65e3756e1cc25869bf0d28.png](https://i-blog.csdnimg.cn/blog_migrate/3643fa3351cb731a1df1debe4dd0fe8d.jpeg)
可以在线导入SVG格式字体,并进行编辑,然后下载来使用,在组件设计中有具体的使用介绍.
如果对于react/vue组件设计原理不熟悉的,可以参考我的之前写的组件设计系列文章:
- 《精通react/vue组件设计》之用纯css打造类materialUI的按钮点击动画并封装成react组件
- 《精通react/vue组件设计》之快速实现一个可定制的进度条组件
- 《精通react/vue组件设计》之基于jsoneditor二次封装一个可实时预览的json编辑器组件(react版)
正文
在开始组件设计之前希望大家对css3和js有一定的基础.我们先看看实现后的组件效果:
![b81dfcc25d4c8eacd94fd6c23668596d.png](https://i-blog.csdnimg.cn/blog_migrate/2fce8c29ee17af6b31082fe998a49ebb.jpeg)
由图可以知道tag组件可以自定义颜色主题(color theme), 可以手动关闭标签, 空状态主要是提供用户数据展示用的, 实现起来很简单,重点在图标的使用上.
1. 组件设计思路
按照之前笔者写的组件设计原则,我们第一步是要确认需求. 一个tag标签组件一般都会有如下需求点:
- 可以改变标签颜色
- 提供关闭标签的配置,让用户可以关闭标签
- 关闭标签的回调,让用户能控制标签关闭后触发的动作
需求收集好之后,作为一个有追求的程序员, 会得出如下线框图:
![c7491defb45bd6f5c60a8d0d59d03041.png](https://i-blog.csdnimg.cn/blog_migrate/91c6dfe361c37f2b86e1005a8ce3daa1.jpeg)
对于react选手来说,如果没用typescript,建议大家都用PropTypes, 它是react内置的类型检测工具,我们可以直接在项目中导入. vue有自带的属性检测方式,这里就不一一介绍了.
2. 基于react实现一个Tag组件
2.1. tag组件框架设计
首先我们先根据需求将组件框架写好,这样后面写业务逻辑会更清晰:
import
有了这个框架,我们来一步步往里面实现内容吧. 根据需求,颜色这个属性好实现,在上述代码中已经实现了, 我们看看closable和onClose如何实现.我们要向关闭tag,实际上是需要将这个标签隐藏,比如说使用display:none,或者从dom中移除, 笔者就参考antd的实现方式,通过display:none来实现.
首先我们要想在react的函数式组件操作dom, 最好的方式是使用ref, 关于ref的使用如果不熟悉的可以参考react官方文档,这里实现如下:
import
通过react的createRef API,我们很方便的拿到了当前的dom对象, 在handleClose可以进行属性的分配. 组件的js代码基本实现完成了,接下来看看css:
.xTag {
margin-bottom: 8px;
margin-right: 8px;
display: inline-block;
border-radius: 4px;
border: 1px solid #d9d9d9;
padding: 0 7px;
font-size: 12px;
line-height: 20px;
white-space: nowrap;
background-color: #fafafa;
&.xTagHasColor {
border-color: transparent;
color: #fff;
.closeBtn {
color: rgba(255, 255, 255, .6)
}
}
.closeBtn {
margin-left: 5px;
color: rgba(0, 0, 0, 0.45);
cursor: pointer;
}
}
健壮性支持:
import
是不是很简单? 这样一个可定制对的tag组件就完成了,关于代码中的css module和classnames的使用大家可以自己去官网学习,非常简单.
3. 基于react实现一个Empty(空状态)组件
这个组件非常好写, 目前常用的空状态组件一般是图片和文字组合, 图片文字都可替换,具体实现如下:
import
这里主要介绍icon-finder的由来.正如文章开始提到的,笔者采用icomoon作为图标库, 我们可以在其官网上定制自己的图标,笔者大概选了40多了免费图标,项目中使用基本够用了.主要介绍一下他的具体功能: 1. 可导入,下载,管理自己的图标库
![908fbb084a79fc9b0d730ae8059498da.png](https://i-blog.csdnimg.cn/blog_migrate/ac7d577a837513ddb42e506e4d13d944.jpeg)
2. 可编辑图标,生成svg图标或者字体图标
![b8e76d17bab2e348a4c6bfa897b3a46f.png](https://i-blog.csdnimg.cn/blog_migrate/592b13630ca4a623b2f5f78e54e695bf.jpeg)
当然国内的iconfont也非常优秀,大家可以多尝试.
我们将下载icomoon图标文件后,会有一个html的demo文件,里面有具体的使用方法和离线编辑功能,如下:
![94ba42ab2614f1b62593ac87e37b00f8.png](https://i-blog.csdnimg.cn/blog_migrate/742e5cd2ffc8be345cc66dc41b011d0b.jpeg)
笔者在这里就不多做介绍了, 其次我们也可以类似于antd一样,将icon封装成react的组件, 这样用起来也非常方便.
最后
后续笔者将会继续实现modal(模态窗), alert(警告提示), drawer(抽屉), tooltip(工具提示条), Skeleton(骨架屏), Message(全局提示), 日期/日历等组件, 来复盘笔者多年的组件化之旅. 如果想学习更多H5游戏, webpack,node,gulp,css3,javascript,nodeJS,canvas数据可视化等前端知识和实战,欢迎在《趣谈前端》专栏学习讨论,共同探索前端的边界。
更多推荐
徐小夕:2年vue项目实战经验汇总zhuanlan.zhihu.com![69f0246c1fc3ed2c2cf3c0d7c54d6d24.png](https://i-blog.csdnimg.cn/blog_migrate/595fdf6186587d4ab88877c211496985.jpeg)
![d2084e1bf621f623c23aab1bd2452312.png](https://i-blog.csdnimg.cn/blog_migrate/a5a70fafcae7033c619bcec566bd5c8c.jpeg)
![66db720c39c39aaa21b911cd24c33c76.png](https://i-blog.csdnimg.cn/blog_migrate/09843617c362644dac46c473be1ac3a4.jpeg)
![30f7e0c0fae579da9a83f5e2ccce48c2.png](https://i-blog.csdnimg.cn/blog_migrate/824781e5d008da1bbab1bac9acda0716.jpeg)
![f8b2d796b2b3930663abbfe46fe44214.png](https://i-blog.csdnimg.cn/blog_migrate/9ed41d760f716b859ad7b87122c7a0f5.jpeg)