跟着官方示例学习 @tanStack-table --- Column Sizing

311 阅读2分钟

🌲系列一:跟着官方示例学习 @tanStack-table --- Basic

🌲系列二:跟着官方示例学习 @tanStack-table --- Header Groups

🌲系列三:跟着官方示例学习 @tanStack-table --- Column Filters

🌲系列四:跟着官方示例学习 @tanStack-table --- Column Ordering

🌲系列五:跟着官方示例学习 @tanStack-table ---Sticky Column Pinning


Resizing

在前面的几篇文章里,我们已经让表格列会动、会钉、会排序。这一篇,我们要再给它加上一个超能力:

✨ 列宽可以自由调整(Resizing)! —— 没错,就是像 Excel 一样,用户可以手动拖动边缘,改变列宽度!

🧩 基础代码

const table = useReactTable({
  data,
  columns,
  columnResizeMode,
  getCoreRowModel: getCoreRowModel(),
});

columnResizeMode API 🔗

🔧 列宽调整的两种模式

可以选择两种调整列宽的体验方式:

const [columnResizeMode, setColumnResizeMode] = useState<ColumnResizeMode>("onChange");
<select onChange={(e) => setColumnResizeMode(e.target.value as ColumnResizeMode)}>
  <option value="onEnd">Resize: "onEnd"</option>
  <option value="onChange">Resize: "onChange"</option>
</select>
  • onChange:拖动过程中实时调整列宽

  • onEnd:拖动结束后才更新列宽

🛠️ 重头戏:头部单元格如何变宽?

<th
  key={header.id}
  style={{ width: header.getSize() }}
>
  {/* 表头内容 */}
  <div
    onMouseDown={header.getResizeHandler()}
    onTouchStart={header.getResizeHandler()}
    className={`resizer ltr ${header.column.getIsResizing() ? "isResizing" : ""}`}
    style={{
      transform:
        columnResizeMode === "onEnd" && header.column.getIsResizing()
          ? `translateX(${table.getState().columnSizingInfo.deltaOffset ?? 0}px)`
          : "",
    }}
  />
</th>

🧪 这里发生了什么魔法?

  • header.getSize():实时获取当前列的宽度(Table 状态 → DOM 映射)

  • header.getResizeHandler():绑定鼠标/触摸拖动事件

  • table.getState().columnSizingInfo.deltaOffset:在onEnd模式下,提供“拖动预览”效果;

  • transform: translateX(...):让拖动的手柄跟着鼠标移动,视觉反馈一流!

🪣 列宽同步到数据单元格

别忘了 <td> 也需要设置 width,否则只会看到头部变化,内容不对齐。

<td
  key={cell.id}
  style={{
    width: cell.column.getSize(),
  }}
>

🔄 一键恢复默认列宽

支持双击把手,恢复默认宽度:

onDoubleClick={() => header.column.resetSize()}

🔍 Resizing 的脑回路长这样

1. 用户拖动 .resizer
⬇️
2. 触发 getResizeHandler()
⬇️
3. 根据 columnResizeMode 更新列宽状态
⬇️
4. 使用 getSize() 显示新宽度
⬇️
5. 在 "onEnd" 模式下,deltaOffset 提供视觉预览

📺 实际演示

Jun-08-2025 10-40-39.gif

Jun-08-2025 10-41-27.gif

🔔 对官方示例代码可能存在一些删减的情况

代码地址🔗:Gitee

官方代码地址🔗: @tanStack/react-table

⚓ resize direction

官方示例代码中提到了一个可以改变方向的属性:columnResizeDirection API🔗

🧩 基础代码

const table = useReactTable({
  data,
  columns,
  columnResizeDirection,
  getCoreRowModel: getCoreRowModel(),
});

'ltr': 左 ➡️ 右

'rtl': 右 ➡️ 左

✈️ 结合 CSS 实现效果

<div style={{ direction: table.options.columnResizeDirection }}>
  <div className="overflow-x-auto">
    <table />
  </div>
</div>

📺 实际演示

Jun-08-2025 11-35-51.gif