React 导读(五)

在React 导读(四)中分享了组件设计最开始考虑的一些事情,不能介绍太矛盾了,其实对于设计来讲是有正反两面的分析的,就跟评论历史事件来看都是要分两面进行分析的。今天我们接着分享剩下的内容,我觉得不一定要求多,但是一定要带着思考来写,有点意识流。

首先弹框和表格是最常用的组件,下面就介绍表格吧。

表格其实是很复杂的一个组件,我们先来看下成熟的表格,然后再来看下我实现的最简单的表格组件是什么样子的。这里就看下比较流行的 antd 吧,我不会分析他的实现和代码,因为这并不利于第一次学习一个组件的封装,一个成熟的组件一般是迭代出来的,越是迭代时间长的组件就更复杂,学习前应该是知道有一个东西,然后将这个东西简化,知道它是什么,然后进行扩展会比较好一点。

这里我将表格组件的实现分为 2 类:配置式和组合式。这 2 种没有哪一种好,各有优缺点:

1. 配置式优点

易于使用

功能声明清晰,具有一定的整体性,代码也不分散

2.配置式缺点

扩展、定制性其实是相对组合式较差

递归性低于组合式

组件结构非标记语言表达,在第一层阅读代码的时候主观上认为不够清晰

3.组合式优点

组件结构标记语言实现,更清晰

扩展性较强,不容易在代码里面形成较多的 if-else 式编程

4. 组合式缺点

使用上相比配置式复杂

代码量较多

这里分的比较开,但是可以是配置+组合的方式来实现组件,做一个制衡。比如:

表头无论是动态、静态构造,最后都是一个固定的配置式数据,也许你还能够自定义列展示;

数据的结构 ID 与 Columns key 进行统一的配置,其实从某种意义上数据与列也是一种约定的模式;

分页组件比较固定,就需要固定配置等等。

对于 antd-table 是依赖于 rc-table 组件进行封装的,props 主要有 2 个:columns、dataSource。

配置上的基础结构,我这里用自己的描述代码:

然后使用的时候通过把配置传递进去就返回了一个你配置的表格:

当然 antd 的体验是不错的,还支持将 Column 组件当作子组件的方式声明,也就是我说的配置+组合的一种结合,会将可读性增强、扩展外置的优点放大。具体可以参考官方文档,这里不能介绍太多:https://ant.design/components/table-cn/

随着需求的扩展,组件需求逐渐增多,就会出现更多的依赖 props,也许会做更多的判断。虽然从需求上我们不能控制这种 if-else 的逻辑,但是我们能够通过的方式来减少单个组件的复杂度。这个是双刃剑,因为可能会有冗余。

就好比有很多 if 的条件,根据组件的种类进行拆分,分成不同的组件,然后让使用者去决定用什么组件,这样一层一层的铺展使用,重的表格可能会有聚合的组件模式,这个又是另外一个问题了。

那么我这里例子里面用到的表格组件怎么弄的呢?我模仿的是 bootstrap-table 的配置方式,然后再配合 React 的一些组件特性拼起来实现的一个 Table 组件。

我这边实现的表格组件只有以下四个组件,其中 SimpleRow 组件是一个 Row 最基础的用法,满足基本的一个表格行。Table.Header 和 Table.Body 分别是对表头和表内容的装饰,主要是样式和布局上的统一。

具体的 Table.jsx 组件代码如下,基本等于就是一个壳:

我们先看一下会如何使用表格吧。

React 组件是能够有命名空间的写法的,比如这里的 Table.的写法。那么我们要统一样式和布局,基本是等于就统一一下 class 就行,我们不能说让使用者自己每次去添加一些共有的代码,所以这里我们要用一个 API React.cloneElement 和 React.Children.map,后面 map 方法可能比较好理解,类似 Array.prototype.map,那么 React.cloneElement 的意思就跟它的表面意思一样:克隆一个元素(https://segmentfault.com/a/1190000008587988),API 可以先看下官网 https://doc.react-china.org/docs/react-api.html#cloneelement 和 https://doc.react-china.org/docs/react-api.html#reactchildrenmap。

先看看一下 Table.Body 的代码吧:

这里的代码可以看 github 上完整的源码:https://github.com/fegg/react-intro/blob/master/src/smarty/table/index.jsx

那么我们组件的结构通过组合的写法构造好了,那么我们的 Columns 在哪儿去声明呢?我们这里也是通过 js 数组对象的方式来声明,结构如下:

这里的配置怎么和表格的列连接起来呢?我这里将业务表格组件的目录划分成了这样:

表头和表内容的声明代码如下:

这样回到最开始那个使用表格的例子,将 header, rows 都添加进入即可,最后整个表格 Row 的效果就是这样子,SimpleRow 的实现代码依然能在业务表格 Github (https://github.com/fegg/react-intro/blob/master/src/components/employee/dataTable/index.jsx)文件中找到:

这种写组件的方法特别费代码,所以是否可以考虑封装成一个业务通用的表格组件呢?这肯定是可以的,将变化的部分通过 props 传入即可,这个工作可以自己动手试试,在我的源码基础上进行修改。还有就是 tableConfig 里边的对象属性,你是能按自己需求进行添加的,可以在看看源码中的配置。

最后表格实现的效果,虽然没有排序、固定表头,但是用来展示信息是已经完善了,比如点击表头进行排序这个可以动手试试,在我组件的基础上应该很好添加:

这里表格组件就实现了,你肯定会想,为什么没有 antd 那么方便实用和强大呢?

(1) 代码少...不足 1KB ^-^;// 当然这是开玩笑的说法

(2) antd-table 和这里介绍的 Table 组件层级是不同的,更接近的应该是 rc-table;(3) 这只是针对最简单的表格使用场景进行设计的,按的是自由编写修改,并不是一个复杂场景的表格设计。

今天先写到这里吧~11点半了,休息一会儿。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180521G1DQJG00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券