开源 UI 库中,唯一同时实现了大表格虚拟化和树表格的 Table 组件

5次阅读

共计 1673 个字符,预计需要花费 5 分钟才能阅读完成。

背景
有这样一个需求,一位 React Suite(以下简称 rsuite)的用户,他需要一个 Table 组件能够像 Jira Portfolio 一样,支持树形数据,同时需要支持大数据渲染。截止到目前(2019 年 1 月 18 日)为止,开源 UI 库中没有找到可以支持的组件,所以 rsuite 在最新的版本中支持这一特性。
接下来,我们看一下 rsuite 中是怎么支持这两个功能?
大表格虚拟化
首先,我们看一下支持大数据渲染,在页面中渲染过多的 DOM 元素会带来性能问题,必须得有一种解决方案去优化它,我们暂且叫做大表格虚拟化。
所谓的大表格虚拟化,其实就是为表格设置一个较大的数据(比如 10000 条数据),然后虚拟一个表格隐藏掉不需要显示的数据。
为了解决让浏览器渲染的大量 DOM 时候出现的性能问题,我们不能把 10000 条数据都渲染到页面,采用一种方式,只渲染可视范围内数据。同时为表格设置一个滚动条,只有在滚动到需要显示的区域时候才渲染该区域的数据,减少的 DOM 数量。

预览地址
以上这是一个 10000 条数据的 Table,渲染后的 HTML 结构是:

我们可以看到在 Table 中只渲染了 14 个 rs-table-row,其中第一个和最后一个是没有 children, 只是一个拥有高度的占位符。每一个 rs-table-row 都是绝对定位,所以即使 Table 中删除一个 Row, 或者新增一个 Row , 也不会改变其他 Row 的位置。在这样的基础上,通过获取滚动条的滚动的位置,就很容易判断当前 Row 的 top 值是否在 Table 的可视范围内,同时更新所有的 Row。
很多优秀的库都实现了这样的功能,原理基本一致,比如 react-virtualized 就提供 Table 组件,但是他不支持 Tree。
树形表格
在表格中展示树形数据的需求,我们见得比较多就像甘特图表格展示那样。它有子父层级关系,可以展开子节点。

这样一个表格,很多 Table 组件都支持,但是如果同时需要支持虚拟化就相对比较麻烦,因为在展开关闭节点的时候需要重新计算显示的 DOM 以及设置滚动条的位置。

在 rsuite Table 组件之前的版本中,渲染的树形表格的 DOM 结构是一棵 Tree。所以首先需要把 Tree 拍平,转换一个一维数组,为每一个节点设置父节点,通过父节点的深度渲染 Tree 节点的相对位置。然后就比较好处理,只需要在点击展开关闭节点按钮的时候,处理好数据的过滤。
安装与使用
rsuite 的 Table 组件的设计,对开发还是非常方便,通过 <Table>、<Column>、<Cell>、<HeaderCell> 组件定义结构,通过赋值 data 属性渲染表格数据。
安装
npm install rsuite –save
如果你在项目只希望用到 Table, 不想安装整个 rsuite 库,你可以单独安装 rsuite-table

示例代码:
import {Table} from ‘rsuite’;

const {Column, HeaderCell, Cell} = Table;
const data = [{id: 1, name: ‘foobar’, email: ‘foobar@xxx.com’}];

ReactDOM.render(
<Table height={400} data={data}>
<Column width={70} align=”center” fixed>
<HeaderCell> 编号 </HeaderCell>
<Cell dataKey=”id” />
</Column>
<Column width={200} fixed>
<HeaderCell> 姓名 </HeaderCell>
<Cell dataKey=”name” />
</Column>
<Column width={200}>
<HeaderCell> 邮箱 </HeaderCell>
<Cell dataKey=”email” />
</Column>
</Table>
);
最后
最后,对于一个成熟的 Table 组件怎么能只有这点功能,所以它还支持:

自定义调整列宽
锁定列
自动换行
排序
分页
编辑
合并单元格
自定义单元格
自动列宽
可展开行

剩下唯一的问题,就是您是否在项目中尝试它。

正文完
 0