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

2019-01-18 13:20:04 +08:00
 simonguo

背景

有这样一个需求,一位 React Suite (以下简称 rsuite)的用户,他需要一个 Table 组件能够像 Jira Portfolio 一样,支持树形数据,同时需要支持大数据渲染。 截止到目前( 2019 年 1 月 17 日)为止,开源 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 组件怎么能只有这点功能,所以它还支持:

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

2549 次点击
所在节点    前端开发
4 条回复
agdhole
2019-01-18 13:29:03 +08:00
这个需求让我想到了上次的帖子“技术选型开除前端”
xiwangzishi
2019-01-18 13:38:11 +08:00
@agdhole 哈哈哈,是的。
fy
2019-01-18 13:40:43 +08:00
@agdhole #1 记忆犹新
chinvo
2019-01-18 13:47:34 +08:00
@agdhole #1 印象深刻

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/528267

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX