踐指南)
TanStack Table v9 Vue 快速上手從安裝到可排序表格的 Headless 實(shí)踐指南【免費(fèi)下載鏈接】table Headless UI for building powerful tables datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table項(xiàng)目地址: https://gitcode.com/gh_mirrors/ta/tableTanStack Table 是一套 headless無頭表格庫它替你管理表格的狀態(tài)與全部邏輯排序、過濾、分頁、選擇等同時把標(biāo)記markup與樣式 100% 交還給你控制。本文基于本倉庫GitHub 加速計(jì)劃 / ta / table中的tanstack/vue-table適配器與docs/framework/vue/quick-start.md快速入門文檔展開先帶你完成從安裝到渲染出第一個 Vue 表格的完整流程再演示如何按需疊加排序等特性并結(jié)合倉庫源碼解釋useTable與 Vue 響應(yīng)式系統(tǒng)如何協(xié)同工作。讀完本文你將掌握 v9 特性化注冊tableFeatures、FlexRender渲染、響應(yīng)式數(shù)據(jù)綁定、createTableHook組合式復(fù)用等關(guān)鍵能力可以直接動手搭建自己的業(yè)務(wù)表格。安裝在 Vue 3 項(xiàng)目中安裝 Vue 適配器只需一條命令npm install tanstack/vue-table從本倉庫packages/vue-table/package.json可以看到當(dāng)前tanstack/vue-table版本為9.1.2其運(yùn)行時依賴為tanstack/store與工作區(qū)內(nèi)的tanstack/table-core并聲明了vue 3.2作為 peerDependencies即要求 Vue 3.2 及以上版本。包以 ESM 形式發(fā)布type: module并額外導(dǎo)出了./experimental-worker-plugin、./flex-render、./static-functions等子路徑。倉庫內(nèi)對應(yīng)的實(shí)現(xiàn)源碼位于packages/vue-table/src其中useTable.ts是核心入口FlexRender.ts負(fù)責(zé)渲染列定義。你的第一個表格下面的單文件組件SFC是完整的把它粘貼到一個 Vue 3 應(yīng)用中即可看到一個可工作的表格。該示例完整取自快速入門文檔其中數(shù)據(jù)、列定義與渲染模板的六個步驟注釋清晰script setup langts import { h, ref } from vue import { FlexRender, tableFeatures, useTable } from tanstack/vue-table import type { ColumnDef } from tanstack/vue-table // 1. 定義數(shù)據(jù)形狀 type Person { firstName: string lastName: string age: number } // 2. v9 新特性聲明該表格用到哪些特性當(dāng)前一個都不用 const features tableFeatures({}) // 3. 定義列 const columns: ArrayColumnDeftypeof features, Person [ { accessorKey: firstName, // accessorKey 簡寫 header: First Name, cell: (info) info.getValue(), }, { accessorFn: (row) row.lastName, // accessorFn 配合自定義 id id: lastName, header: () h(span, Last Name), cell: (info) h(i, info.getValuestring()), }, { accessorKey: age, header: () Age, }, ] // 4. 把數(shù)據(jù)放進(jìn) ref讓表格對變化做出響應(yīng) const data refArrayPerson([ { firstName: tanner, lastName: linsley, age: 24 }, { firstName: tandy, lastName: miller, age: 40 }, { firstName: joe, lastName: dirte, age: 45 }, ]) // 5. 創(chuàng)建表格實(shí)例 const table useTable({ key: person-table, // 用 key 向 devtools 注冊該表格 features, columns, data, }) /script !-- 6. 用表格實(shí)例提供的 API 渲染標(biāo)記 -- template table thead tr v-forheaderGroup in table.getHeaderGroups() :keyheaderGroup.id th v-forheader in headerGroup.headers :keyheader.id FlexRender v-if!header.isPlaceholder :headerheader / /th /tr /thead tbody tr v-forrow in table.getRowModel().rows :keyrow.id td v-forcell in row.getAllCells() :keycell.id FlexRender :cellcell / /td /tr /tbody /table /template這個示例有幾個要點(diǎn)值得展開tableFeatures({})聲明表格使用的可選特性。只注冊真正需要的特性既能保持打包體積更小也能讓 TypeScript 對表格實(shí)例給出更精確的類型。其實(shí)現(xiàn)位于packages/table-core/src/helpers/tableFeatures.ts內(nèi)部會對特性與行模型槽位做校驗(yàn)ValidateFeatureSlots防止注冊了特性卻缺少配套行模型的類型錯誤。核心行模型core row model始終內(nèi)置。而排序、過濾、分頁這類特性行模型則在你需要時直接注冊到features對象上下文排序示例會看到。直接把dataref 傳給useTable即可保持響應(yīng)式。之后data.value [...]重新賦值表格會自動更新無需手動調(diào)用刷新。FlexRender負(fù)責(zé)渲染列定義中的header、cell、footer無論是純字符串、使用h的渲染函數(shù)還是 Vue 組件它都能統(tǒng)一處理。從packages/vue-table/src/FlexRender.ts源碼看FlexRender組件同時支持簡寫模式FlexRender :cellcell /、:header、:footer與舊版模式:render:props其底層flexRender()函數(shù)對函數(shù)型渲染會先調(diào)用拿到結(jié)果若是 VNode 直接返回若是組件對象則用h()包裝在注冊了列分組grouping特性時它還會對aggregated聚合回退到columnDef.cell、placeholder分組內(nèi)的重復(fù)值渲染為null等特殊單元格模式做分支處理。key選項(xiàng)是可選的除非你使用 TanStack Table Devtools。devtools 通過key識別表格并通過tanstack/vue-table-devtools中的useTanStackTableDevtools(table)注冊表格。倉庫中examples/vue/basic-use-table提供了該示例的可運(yùn)行版本它用createColumnHelper定義了 6 列firstName、lastName、age、visits、status、progress包含表頭、表格主體以及頁腳合計(jì)行src/App.tsx中還可以看到useTanStackTableDevtools(table)的完整用法。你可以在該目錄下查看src/App.tsx與tests中的測試來驗(yàn)證端到端行為。useTable 與 Vue 響應(yīng)式源碼級原理為什么直接把ref傳給useTable就能自動同步看packages/vue-table/src/useTable.ts的實(shí)現(xiàn)類型層面TableOptionsWithReactiveData把所有選項(xiàng)尤其是data放寬為MaybeRefT即選項(xiàng)可以是普通值、ref或computed。運(yùn)行時getOptionsWithReactiveValues()用unref()逐個解包選項(xiàng)得到解析后的配置getReactiveOptionDeps()則收集所有解包后的依賴值。useTable內(nèi)部調(diào)用mergeProxy把調(diào)用方傳入的features與適配器注入的coreReactivityFeature: vueReactivity()合并——這正是 Vue 響應(yīng)式能力接入點(diǎn)。據(jù) Table State (Vue) Guide 說明該適配器的核心只讀 atom 是 Vuecomputed可寫 atom 是shallowRef訂閱由watch(..., { flush: sync })支撐。兩個watch均帶immediate: true分別負(fù)責(zé)當(dāng)任一響應(yīng)式選項(xiàng)依賴變化時調(diào)用table.setOptions同步配置當(dāng)通過options.state傳入的受控狀態(tài)切片變化時同步表格選項(xiàng)。配合onScopeDispose(() reactivity.unmount?.())在組件卸載時自動清理。返回的表格實(shí)例上額外掛載了Subscribe方法用于創(chuàng)建響應(yīng)式渲染邊界children函數(shù)內(nèi)讀取了哪些table.atomsVue 就只追蹤這些讀取實(shí)現(xiàn)細(xì)粒度的依賴收集。添加一個特性排序v9 中所有特性都是按需注冊opt-in的。要讓列可排序在tableFeatures中注冊rowSortingFeature與sortedRowModel并在表頭綁定點(diǎn)擊處理器即可script setup langts import { h, ref } from vue import { FlexRender, createSortedRowModel, rowSortingFeature, sortFns, tableFeatures, useTable, } from tanstack/vue-table const features tableFeatures({ rowSortingFeature, // 啟用排序 API 與狀態(tài) sortedRowModel: createSortedRowModel(), // 客戶端排序 sortFns, }) // 列與數(shù)據(jù)與上文相同 const table useTable({ key: person-table, features, columns, data, }) /script template table thead tr v-forheaderGroup in table.getHeaderGroups() :keyheaderGroup.id th v-forheader in headerGroup.headers :keyheader.id :style{ cursor: header.column.getCanSort() ? pointer : undefined, } clickheader.column.getToggleSortingHandler()?.($event) template v-if!header.isPlaceholder FlexRender :headerheader / {{ { asc: , desc: }[header.column.getIsSorted() as string] }} /template /th /tr /thead !-- tbody 與上文相同 -- /table /template點(diǎn)擊表頭現(xiàn)在會在升序、降序、不排序三種狀態(tài)間循環(huán)切換。排序機(jī)制的底層實(shí)現(xiàn)可參考packages/table-core/src/features/row-sorting/createSortedRowModel.ts它創(chuàng)建一個記憶化memoized的排序行模型工廠讀取相關(guān)狀態(tài) atom 與選項(xiàng)后返回行模型函數(shù)供表格行模型管道調(diào)用并聯(lián)動分頁自動重置table_autoResetPageIndex等行為。其他所有特性都遵循同樣的模式在tableFeatures中注冊特性及其行模型工廠如果有然后使用它給表格、列、行新增的 API。關(guān)于自定義排序函數(shù)、多列排序multi-sorting與按列選項(xiàng)如sortFn、sortDescFirst可繼續(xù)閱讀 Sorting Guide 與 Sorting 示例。補(bǔ)充一個來自該指南的實(shí)用建議排序函數(shù)注冊表sortFns若整個展開{ ...sortFns }會把所有內(nèi)置排序函數(shù)打進(jìn)包內(nèi)更推薦只注冊用到的函數(shù)如sortFn_alphanumeric、sortFn_text、sortFn_datetime或直接在列的sortFn選項(xiàng)上傳單個函數(shù)。列默認(rèn)的sortFn: auto會根據(jù)列數(shù)據(jù)類型從注冊表中解析為alphanumeric、text或datetime。表格狀態(tài)讀、寫與外部托管v9 的表格狀態(tài)由 TanStack Store atom 支撐Vue 適配器將其接入 Vue 響應(yīng)式因此大多數(shù)情況下你不需要自己管理狀態(tài)。以下是來自 Table State (Vue) Guide 的核心結(jié)論它是理解其余一切的基礎(chǔ)默認(rèn)內(nèi)部托管不傳initialState、atoms、state或任何on[State]Change表格就自己管理狀態(tài)。三個狀態(tài)表面table.baseAtoms是由解析后的初始狀態(tài)創(chuàng)建的內(nèi)部可寫 atomtable.atoms是按已注冊狀態(tài)切片暴露的只讀派生 atomtable.store是把所有已注冊table.atoms匯總后的只讀扁平 store。按特性切片只有注冊到features的特性才會創(chuàng)建狀態(tài)切片。未注冊rowSelectionFeature時table.atoms.rowSelection在 TypeScript 層就會報(bào)錯這也是 tree-shakeable 與類型精確的來源。讀狀態(tài)最推薦用窄范圍讀取table.atoms.slice.get()如table.atoms.pagination.get()需要當(dāng)前完整快照時用table.store.get()。因?yàn)?Vue 表格 atom 底層是 ref/computed在模板、computed(...)、watch(...)或table.Subscribe內(nèi)讀取會自動參與依賴追蹤在 JSX/渲染函數(shù)中可用table.Subscribe的children函數(shù)顯式聲明要追蹤的 atom 讀取形成細(xì)粒度的響應(yīng)式渲染邊界。寫狀態(tài)優(yōu)先使用特性 API如table.setSorting(...)、table.setColumnFilters(...)、column.toggleVisibility()、row.toggleSelected()或分頁的table.nextPage()、table.previousPage()、table.setPageIndex(0)、table.setPageSize(25)僅需起始值時用initialState確實(shí)要直接寫內(nèi)部狀態(tài)時才用table.baseAtoms.pagination.set(...)這類低層接口應(yīng)很罕見。受控狀態(tài)當(dāng)應(yīng)用需要擁有某個狀態(tài)切片時可以用外部 TanStack Store atomcreateAtomatoms選項(xiàng) useSelector訂閱需要tanstack/vue-store或 Vue ref/computedstateon[State]Change兩種方式托管。注意onSortingChange應(yīng)與state.sorting成對出現(xiàn)回調(diào)收到的 updater 可能是原始值也可能是函數(shù)需要像updater instanceof Function ? updater(sorting.value) : updater這樣處理。重置特性重置 API如table.resetSorting()、table.resetPagination()默認(rèn)重置到table.initialState傳入true則重置為該特性自身的空白默認(rèn)狀態(tài)而核心的table.reset()只重置內(nèi)部 base atoms不應(yīng)用作外部 atom 托管切片的常規(guī)重置手段。組合式復(fù)用createTableHook當(dāng)應(yīng)用中多張表格共享特性、行模型與組件約定時可以用createTableHook一次性定義并復(fù)用。快速入門文檔給出的核心模式如下const features tableFeatures({ rowSortingFeature, sortedRowModel: createSortedRowModel(), sortFns, }) const { useAppTable, createAppColumnHelper } createTableHook({ features, })從packages/vue-table/src/createTableHook.ts的實(shí)現(xiàn)看createTableHook會把默認(rèn)表格選項(xiàng)與每次調(diào)用傳入的選項(xiàng)合并后轉(zhuǎn)交useTable并返回useAppTable創(chuàng)建表格實(shí)例并在其上掛載AppTable、AppCell、AppHeader、AppFooter四個包裝組件、上下文綁定的FlexRender以及通過tableComponents注冊的組件createAppColumnHelper預(yù)綁定TFeatures與注冊組件的列助手使 cell/header/footer 渲染 props 能直接暴露這些綁定組件useTableContext/useCellContext/useHeaderContext分別在table.AppTable、table.AppCell、table.AppHeader/table.AppFooter內(nèi)部讀取對應(yīng)上下文并獲得追加了cellComponents/headerComponents與FlexRender的擴(kuò)展實(shí)例。若在錯誤的作用域調(diào)用會拋出帶明確提示的錯誤。完整的組合模式包括預(yù)綁定 cell 與 header 組件、通過AppCell插槽注入上下文等見 Composable Tables Guideexamples/vue/composable-tables目錄下有可運(yùn)行示例。下一步該看什么表格狀態(tài)Table State Guide 是理解其余一切的基礎(chǔ)文檔覆蓋原子狀態(tài)、受控狀態(tài)與外部托管。特性指南每個特性都有獨(dú)立指南例如 Column Filtering、Pagination、Row Selection、Column Visibility此外還有分組grouping、聚合aggregation、行固定row-pinning、單元格選擇cell-selection、虛擬化virtualization等指南全部位于docs/framework/vue/guide/目錄??蛇\(yùn)行示例瀏覽 Vue 示例目錄從基礎(chǔ)表格到各特性演示一應(yīng)俱全。除basic-use-table外sorting、filters、pagination、row-selection、virtualized-rows、with-tanstack-query等示例覆蓋了常見業(yè)務(wù)場景并帶有 vitest 測試可以本地運(yùn)行驗(yàn)證。調(diào)試若需要使用 TanStack Table Devtools 可視化調(diào)試表格狀態(tài)記得為每張表傳入唯一key并在組件中調(diào)用useTanStackTableDevtools(table)?!久赓M(fèi)下載鏈接】table Headless UI for building powerful tables datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table項(xiàng)目地址: https://gitcode.com/gh_mirrors/ta/table創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考