)
前端UI組件【免費下載鏈接】table Headless UI for building powerful tables datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table項目地址https://gitcode.com/gh_mirrors/ta/table點擊查看免費下載TanStack Table即本倉庫 ta/table 所鏡像的 headless 表格框架中列寬Column Sizing是每個表格在渲染時都必須處理的基礎(chǔ)能力。ColumnDef_ColumnSizing是定義在 packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts 中的列定義ColumnDef混入接口它只包含三個可選屬性size、minSize、maxSize卻完整地決定了每列初始寬度、可收縮下限與可拉伸上限。讀完本文你將理解這三個參數(shù)的優(yōu)先級、鉗制clamp算法、與columnSizing狀態(tài)及columnResizing交互的關(guān)系并能基于源碼寫出可復制的列寬配置。一、接口總覽三個可選數(shù)值屬性ColumnDef_ColumnSizing是列定義接口的“切片”之一當表實例注冊了columnSizingFeature后每個ColumnDef都會獲得這三個可選屬性。完整定義如下見 columnSizingFeature.types.tsexport interface ColumnDef_ColumnSizing { /** * Upper bound used when resolving this columns size. */ maxSize?: number /** * Lower bound used when resolving this columns size. */ minSize?: number /** * Initial size used before column sizing state overrides it. */ size?: number }三個屬性的語義非常明確屬性類型默認值含義sizenumber150列的初始尺寸像素在columnSizing狀態(tài)覆蓋它之前生效minSizenumber20解析該列尺寸時使用的下界最小寬度maxSizenumberNumber.MAX_SAFE_INTEGER解析該列尺寸時使用的上界最大寬度值得注意的是這三個屬性的默認值并非寫在接口上而是由 feature 的內(nèi)置默認列定義提供。在 columnSizingFeature.utils.ts 中export function getDefaultColumnSizingColumnDef() { return { size: 150, minSize: 20, maxSize: Number.MAX_SAFE_INTEGER, } }也就是說不配置任何列寬時TanStack Table 的每一列默認寬 150px、最小可縮到 20px、最大理論上不限。該默認值被columnSizingFeature的getDefaultColumnDef鉤子注入到每個列定義上見 columnSizingFeature.ts。二、size初始尺寸與狀態(tài)覆蓋機制size的官方注釋是 “Initial size used before column sizing state overrides it”在 column sizing 狀態(tài)覆蓋它之前使用的初始尺寸。這揭示了一條重要的解析順序state.columnSizing[column.id]的優(yōu)先級高于columnDef.size。也就是說size并不是“最終渲染寬度”而是“初始建議寬度”。一旦用戶通過拖拽列頭邊緣調(diào)整了列寬或者程序通過table.setColumnSizing()/onColumnSizingChange寫入了該列的尺寸state.columnSizing中記錄的數(shù)值就會覆蓋size。從源碼看columnSizingFeature的初始狀態(tài)是一個空對象getDefaultColumnSizingState()返回makeObjectMap()所以默認情況下每列都回退到columnDef.size見 columnSizingFeature.utils.ts。對應的單元測試也驗證了這一點未配置size時column_getSize()返回內(nèi)置默認值150配置size: 200時葉子表頭header.getSize()返回200當state.columnSizing中記錄{ a: 250 }時即使columnDef.size是100最終解析結(jié)果也是250見 columnSizingFeature.utils.test.ts。分組表頭如何繼承 sizesize不僅作用于葉子列。對于分組列擁有子列的父列其表頭尺寸是所有后代葉子列尺寸之和。測試用例證明外層分組outer包含innerinner包含a(100px)與b(200px)此時inner.getSize()與outer.getSize()均為300一旦通過table.setColumnSizing({ a: 400 })修改葉子列寬兩級分組表頭會同步重算為600見 columnSizingFeature.utils.test.ts。三、minSize最小寬度的下界約束minSize定義了列在解析尺寸時允許的最小值。它有兩層作用限制拖拽縮小的下限當用戶拖動列頭 resize handle 時即使拖拽量再大最終解析出的尺寸也不會低于minSize鉗制非法狀態(tài)值如果columnSizing狀態(tài)中被人為寫入了一個小于minSize的數(shù)值解析結(jié)果同樣會被抬升回minSize。源碼中的鉗制邏輯位于column_getSize()見 columnSizingFeature.utils.tsreturn Math.min( Math.max( column.columnDef.minSize ?? defaultSizes.minSize, columnSize ?? column.columnDef.size ?? defaultSizes.size, ), column.columnDef.maxSize ?? defaultSizes.maxSize, )解析順序可以概括為三步候選寬度 state.columnSizing[column.id]若存在→ 否則columnDef.size→ 否則內(nèi)置默認150先用Math.max與minSize比較低于下限則抬升下限 columnDef.minSize或內(nèi)置默認20再用Math.min與maxSize比較超過上限則壓低上限 columnDef.maxSize或內(nèi)置默認Number.MAX_SAFE_INTEGER。測試用例should clamp to minSize驗證列定義minSize: 50、狀態(tài)寫入{ a: 5 }最終column_getSize()返回50見 columnSizingFeature.utils.test.ts。四、maxSize最大寬度的上界約束maxSize與minSize對稱定義了列寬解析的上限。默認值為Number.MAX_SAFE_INTEGER意味著默認情況下列寬沒有實際的上限只有顯式配置maxSize時才會生效。它的典型應用場景包括內(nèi)容很長的列如“描述”“備注”限制其最大寬度以避免過度擠壓其他列固定寬度徽標列、操作按鈕列防止其在容器變寬時被拉伸與minSize組合形成“固定區(qū)間”讓列只能在區(qū)間內(nèi)伸縮。測試用例should clamp to maxSize驗證列定義size: 500, maxSize: 300且無狀態(tài)覆蓋時解析結(jié)果被鉗制為300見 columnSizingFeature.utils.test.ts。需要特別注意的是minSize與maxSize同時存在時鉗制順序先max(minSize, 候選值)再min(maxSize, …)。如果配置的minSize maxSize最終結(jié)果會落到maxSize上因此配置時應保證minSize size maxSize。五、三個屬性如何協(xié)作完整解析鏈路把上面的內(nèi)容串起來一列“最終渲染寬度”的解析鏈路如下候選值 state.columnSizing[column.id] ?? columnDef.size ?? 150內(nèi)置默認 最終值 clamp(候選值, minSize 或 20, maxSize 或 Number.MAX_SAFE_INTEGER)這條鏈路體現(xiàn)在column_getSize()中而其上層 API 鏈為column.getSize()—— 解析該列當前寬度葉子列使用上述 clamp 結(jié)果分組列遞歸求和子列header.getSize()—— 表頭的渲染寬度葉子表頭取列寬分組表頭遞歸累加table.getTotalSize()/getStartTotalSize()/getCenterTotalSize()/getEndTotalSize()—— 整表及固定區(qū)域的合計寬度。這些 API 的 memo 依賴被精心設(shè)計葉子列的getSize只依賴columnSizing狀態(tài)中該列自己的條目而分組表頭與getStart/getAfter偏移量則依賴整個columnSizing狀態(tài)以保證子列尺寸變化時父級與偏移量能正確失效重算見 columnSizingFeature.ts。此外table.getColumnOffsets()會一次性構(gòu)建“全部 / 居中 / 起始固定 / 結(jié)束固定”四個區(qū)域的 start/after 偏移表ColumnOffsetsByPosition并以此支撐column.getStart()/column.getAfter()的 O(1) 查詢見 columnSizingFeature.utils.ts。偏移量的正確性直接影響固定列pinning場景下的布局。六、與columnSizing狀態(tài)、columnResizing的關(guān)系理解ColumnDef_ColumnSizing還需要分清它和另外兩個相鄰概念1.state.columnSizing已提交尺寸狀態(tài)類型為Recordstring, number以列 id 為鍵、像素數(shù)為值見 columnSizingFeature.types.ts。它是“運行時覆蓋層”優(yōu)先級高于columnDef.size。相關(guān) APItable.setColumnSizing(updater)—— 更新已提交尺寸table.resetColumnSizing(defaultState?)—— 重置為initialState.columnSizing或空對象column.resetSize()—— 只移除當前列的尺寸覆蓋使其回退到columnDef.size與默認值見 columnSizingFeature.utils.ts。column_resetSize的實現(xiàn)值得留意它遍歷當前狀態(tài)僅剔除當前列 id 的條目、保留其余列再通過onColumnSizingChange提交新狀態(tài)。2.columnResizing拖拽過程狀態(tài)ColumnDef_ColumnSizing只管“靜態(tài)約束”而實際拖拽行為由ColumnDef_ColumnResizing提供每個列定義還有一個enableResizing?: boolean開關(guān)表級選項enableColumnResizing、columnResizeModeonChange | onEnd、columnResizeDirectionltr | rtl則決定拖拽時的提交時機與方向見 columnResizingFeature.types.ts。拖拽過程中產(chǎn)生的臨時狀態(tài)columnSizingStart、deltaOffset、isResizingColumn等與最終提交到columnSizing的值是分離的onChange模式下拖拽過程會持續(xù)提交尺寸onEnd模式下拖拽結(jié)束才提交。無論哪種模式提交后的值最終都要經(jīng)過本文第三、四節(jié)所述的minSize/maxSize鉗制。七、實戰(zhàn)配置示例下面以本倉庫 examples/react/column-sizing 為代表的用法給出一個完整的列寬配置。這里以 React 風格示意其余框架的 API 形態(tài)一致如 Vue、Solid、Svelte 的列定義均可使用同樣的三個屬性import { createColumnHelper } from tanstack/react-table type Person { id: string name: string email: string description: string } const columnHelper createColumnHelperPerson() const columns [ columnHelper.accessor(id, { size: 60, // 窄列初始 60px minSize: 40, // 最小 40px maxSize: 80, // 最大 80px保持固定感 }), columnHelper.accessor(name, { size: 180, minSize: 100, }), columnHelper.accessor(email, { size: 240, minSize: 160, }), columnHelper.accessor(description, { size: 320, minSize: 200, maxSize: 600, // 防止描述列無限拉伸 }), ]配套的表級配置const table useTable({ columns, data, enableColumnResizing: true, // 開啟列寬拖拽 columnResizeMode: onChange, // 拖拽過程中實時提交性能要求高可改 onEnd // state: { columnSizing: { name: 200 } }, // 外部受控寫法可覆蓋 columnDef.size })渲染列寬的方式在col或th/td上直接使用header.column.getSize()葉子列與header.getSize()分組表頭輸出像素寬度需要固定列偏移時使用column.getStart()/column.getAfter()需要整表總寬或固定區(qū)總寬時使用table.getTotalSize()等四個 total 系列 API。八、常見問題與最佳實踐為什么設(shè)置了size卻不生效檢查state.columnSizing或initialState.columnSizing中是否已存在該列的條目——狀態(tài)值優(yōu)先于size。需要恢復時調(diào)用column.resetSize()或table.resetColumnSizing()。列寬拖拽超過minSize/maxSize后仍顯示為邊界值這是正?,F(xiàn)象column_getSize()的 clamp 保證解析結(jié)果永遠落在[minSize, maxSize]區(qū)間內(nèi)。分組表頭的寬度總和與子列不一致分組表頭寬度是葉子列遞歸求和的結(jié)果修改任意葉子列寬后父表頭會同步重算若遇到不一致確認列的visible狀態(tài)隱藏列不參與求和與columnSizing提交是否正確。固定列與列寬配合列寬偏移量getStart/getAfter依賴完整的可見列寬列表啟用columnPinning后三個固定區(qū)域會分別計算偏移與合計寬度配置列寬時需保證 min/max 區(qū)間與固定區(qū)域布局匹配。Feature 注冊前提本接口由columnSizingFeature提供。按照 docs/guide/features.md 的說明TanStack Table v9 采用插件架構(gòu)只有注冊了該 featureColumnDef才具備size/minSize/maxSize三個屬性以及column.getSize()等 API未注冊時 TypeScript 類型上也不會出現(xiàn)這些 API。九、源碼與測試索引如果想深入閱讀本文涉及的全部實現(xiàn)細節(jié)可以在本倉庫中按以下路徑追蹤接口定義packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts尺寸解析與鉗制算法packages/table-core/src/features/column-sizing/columnSizingFeature.utils.tsFeature 注冊與 memo 依賴packages/table-core/src/features/column-sizing/columnSizingFeature.ts拖拽相關(guān)選項enableResizing、columnResizeMode等packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts單元測試覆蓋默認值、clamp、reset、偏移量、分組重算等全部行為packages/table-core/tests/unit/features/column-sizing/columnSizingFeature.utils.test.ts框架示例examples/react/column-sizing相關(guān)指南docs/guide/columns.md、docs/guide/features.md掌握size/minSize/maxSize三者與columnSizing狀態(tài)的優(yōu)先級關(guān)系就能精準控制每一列的初始寬度、伸縮邊界并理解列寬拖拽、固定列等復雜布局背后的解析原理。贊分享前端UI組件【免費下載鏈接】table Headless UI for building powerful tables datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table項目地址https://gitcode.com/gh_mirrors/ta/table點擊查看免費下載相關(guān)推薦深入解析 TanStack Table 的 ColumnOffsets 接口列偏移量與列寬定位的實現(xiàn)原理深入解析 TanStack Table 的 ColumnOffsets 接口列偏移量與列寬定位的實現(xiàn)原理 導讀 ColumnOffsets 是 TanStac前端UI組件TanStack Table 列級尺寸調(diào)整開關(guān)ColumnDef.enableResizing 接口詳解與列寬調(diào)整實戰(zhàn)TanStack Table 列級尺寸調(diào)整開關(guān)ColumnDef.enableResizing 接口詳解與列寬調(diào)整實戰(zhàn) 導讀 在 TanStack Table前端UI組件TanStack Table 列寬調(diào)整核心 API 深入解析Table_ColumnResizing 接口的 resetHeaderSizeInfo 與 setColumnResizingTanStack Table 列寬調(diào)整核心 API 深入解析Table_ColumnResizing 接口的 resetHeaderSizeInfo 與 se前端UI組件創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考