列大小调整指南

示例

想要直接跳到实现部分吗?请查看以下示例:

API

列大小调整 API

列大小调整指南

列大小调整功能允许您选择性地指定每列的宽度,包括最小和最大宽度。它还允许您和您的用户随意动态更改所有列的宽度,例如通过拖动列标题。

列宽

默认情况下,为列提供以下度量选项:

tsx
export const defaultColumnSizing = {
  size: 150,
  minSize: 20,
  maxSize: Number.MAX_SAFE_INTEGER,
}
export const defaultColumnSizing = {
  size: 150,
  minSize: 20,
  maxSize: Number.MAX_SAFE_INTEGER,
}

这些默认值可以被 tableOptions.defaultColumn 和单个列定义覆盖,顺序如下。

tsx
const columns = [
  {
    accessorKey: 'col1',
    size: 270, //为此列设置列大小
  },
  //...
]

const table = useReactTable({
  //覆盖默认列大小调整
  defaultColumn: {
    size: 200, //起始列大小
    minSize: 50, //在列大小调整期间强制执行
    maxSize: 500, //在列大小调整期间强制执行
  },
})
const columns = [
  {
    accessorKey: 'col1',
    size: 270, //为此列设置列大小
  },
  //...
]

const table = useReactTable({
  //覆盖默认列大小调整
  defaultColumn: {
    size: 200, //起始列大小
    minSize: 50, //在列大小调整期间强制执行
    maxSize: 500, //在列大小调整期间强制执行
  },
})

列“大小”以数字形式存储在表格状态中,通常解释为像素单位值,但您可以根据需要将这些列大小调整值连接到 CSS 样式。

作为无头实用程序,列大小调整的表格逻辑实际上只是状态的集合,您可以根据需要将其应用于自己的布局(我���上面的示例实现了此逻辑的 2 种样式)。您可以通过多种方式应用这些宽度度量:

  • 语义 table 元素或以表格 CSS 模式显示的任何元素
  • div/span 元素或以非表格 CSS 模式显示的任何元素
    • 具有严格宽度的块级元素
    • 具有严格宽度的绝对定位元素
    • 具有宽松宽度的 Flexbox 定位元素
    • 具有宽松宽度的网格定位元素
  • 实际上是任何可以将单元格宽度插值到表格结构中的布局机制。

这些方法中的每一种都有其自身的权衡和限制,这些权衡和限制通常是 UI/组件库或设计系统持有的观点,幸运的是不是您 😉。

列大小调整

TanStack Table 提供了内置的列大小调整状态和 API,使您可以轻松地在表格 UI 中实现列大小调整,并提供各种 UX 和性能选项。

启用列大小调整

默认情况下,column.getCanResize() API 将默认为所有列返回 true,但您可以使用 enableColumnResizing 表格选项禁用所有列的列大小调整,或使用 enableResizing 列选项禁用单个列的列大小调整。

tsx
const columns = [
  {
    accessorKey: 'id',
    enableResizing: false, //仅禁用此列的大小调整
    size: 200, //起始列大小
  },
  //...
]
const columns = [
  {
    accessorKey: 'id',
    enableResizing: false, //仅禁用此列的大小调整
    size: 200, //起始列大小
  },
  //...
]

列大小调整模式

默认情况下,列大小调整模式设置为 "onEnd"。这意味着在用户完成调整列大小(拖动)之前,column.getSize() API 不会返回新的列大小。通常,当用户调整列大小时,会显示一个小的 UI 指示器。

在 React TanStack Table 适配器中,实现 60 fps 列大小调整渲染可能很困难,具体取决于表格或网页的复杂性,"onEnd" 列大小调整模式可以是一个很好的默认选项,以避免在用户调整列大小时出现卡顿或延迟。这并不是说在使用 TanStack React Table 时无法实现 60 fps 列大小调整渲染,但您可能需要进行一些额外的记忆化或其他性能优化才能实现此目的。

高级列大小调整性能提示将在下文中讨论。

如果要将列大小调整模式更改为 "onChange" 以立即进行列大小调整渲染,可以使用 columnResizeMode 表格选项执行此操作。

tsx
const table = useReactTable({
  //...
  columnResizeMode: 'onChange', //将列大小调整模式更改为“onChange”
})
const table = useReactTable({
  //...
  columnResizeMode: 'onChange', //将列大小调整模式更改为“onChange”
})

列大小调整方向

默认情况下,TanStack Table 假定表格标记以从左到右的方向布局。对于从右到左的布局,您可能需要将列大小调整方向更改为 "rtl"

tsx
const table = useReactTable({
  //...
  columnResizeDirection: 'rtl', //对于某些区域设置,将列大小调整方向更改为“rtl”
})
const table = useReactTable({
  //...
  columnResizeDirection: 'rtl', //对于某些区域设置,将列大小调整方向更改为“rtl”
})

将列大小调整 API 连接到 UI

有一些非常方便的 API 可用于将列大小调整拖动交互连接到 UI。

列大小 API

要将列的大小应用于列标题单元格、数据单元格或页脚单元格,可以使用以下 API:

ts
header.getSize()
column.getSize()
cell.column.getSize()
header.getSize()
column.getSize()
cell.column.getSize()

如何将这些大小样式应用于标记取决于您,但通常使用 CSS 变量或内联样式来应用列大小。

tsx
<th
  key={header.id}
  colSpan={header.colSpan}
  style={{ width: `${header.getSize()}px` }}
>
<th
  key={header.id}
  colSpan={header.colSpan}
  style={{ width: `${header.getSize()}px` }}
>

但是,如高级列大小调整性能部分中所述,您可能需要考虑使用 CSS 变量将列大小应用于标记。

列大小调整 API

TanStack Table 提供了一个预构建的事件处理程序,使您的拖动交互易于实现。这些事件处理程序只是调用其他内部 API 以更新列大小调整状态并重新渲染表格的便捷函数。使用 header.getResizeHandler() 连接到列大小调整拖动交互,同时适用于鼠标和触摸事件。

tsx
<ColumnResizeHandle
  onMouseDown={header.getResizeHandler()} //适用于桌面
  onTouchStart={header.getResizeHandler()} //适用于移动设备
/>
<ColumnResizeHandle
  onMouseDown={header.getResizeHandler()} //适用于桌面
  onTouchStart={header.getResizeHandler()} //适用于移动设备
/>
带有 ColumnSizingInfoState 的列大小调整指示器

TanStack Table 跟踪一个名为 columnSizingInfo 的状态对象,您可以使用该对象渲染列大小调整指示器 UI。

jsx
<ColumnResizeIndicator
  style={{
    transform: header.column.getIsResizing()
      ? `translateX(${table.getState().columnSizingInfo.deltaOffset}px)`
      : '',
  }}
/>
<ColumnResizeIndicator
  style={{
    transform: header.column.getIsResizing()
      ? `translateX(${table.getState().columnSizingInfo.deltaOffset}px)`
      : '',
  }}
/>

高级列大小调整性能

如果您正在创建大型或复杂的表格(并且正在使用 React 😉),您可能会发现,如果您没有向渲染逻辑添加适当的记忆化,则用户在调整列大小时可能会遇到性能下降的情况。

我们创建了一个高性能列大小调整示例,演示了如何使用可能渲染缓慢的复杂表格实现 60 fps 列大小调整渲染。建议您查看该示例以了解其实现方式,但需要记住以下基本事项:

  1. 不要在每个标题和每个数据单元格上使用 column.getSize()。相反,预先一次性计算所有列宽,并进行记忆化
  2. 在调整大小时对表格主体进行记忆化。
  3. 使用 CSS 变量将列宽传递给表格单元格。

如果遵循这些步骤,您应该会在调整列大小时看到显着的性能改进。

如果您未使用 React,而是使用 Svelte、Vue 或 Solid 适配器,则可能不必太担心这一点,但类似的原则也适用。