開源 UI 庫中,唯一同時實現了大表格虛擬化和樹表格的 Table 組件

背景

有這樣一個需求,一位 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: '[email protected]' }];

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 組件怎麼能只有這點功能,所以它還支持:

  • 自定義調整列寬
  • 鎖定列
  • 自動換行
  • 排序
  • 分頁
  • 編輯
  • 合併單元格
  • 自定義單元格
  • 自動列寬
  • 可展開行

剩下唯一的問題,就是您是否在項目中嘗試它。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章