@tanstack/vue-table 9.2.5 → 9.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/useTable.d.ts +7 -4
- package/dist/useTable.js +2 -2
- package/package.json +2 -2
- package/skills/getting-started/SKILL.md +29 -89
- package/skills/{create-table-hook/SKILL.md → getting-started/references/create-table-hook.md} +15 -42
- package/skills/{with-tanstack-query/SKILL.md → getting-started/references/with-tanstack-query.md} +17 -26
- package/skills/{with-tanstack-virtual/SKILL.md → getting-started/references/with-tanstack-virtual.md} +13 -24
- package/skills/migrate-v8-to-v9/SKILL.md +26 -163
- package/skills/migrate-v8-to-v9/references/adapter-migration.md +51 -0
- package/skills/table-state/SKILL.md +28 -154
- package/skills/table-state/references/reactivity.md +126 -0
package/dist/useTable.d.ts
CHANGED
|
@@ -3,8 +3,11 @@ import { RowData, Table, TableFeatures, TableOptions } from "@tanstack/table-cor
|
|
|
3
3
|
//#region src/useTable.d.ts
|
|
4
4
|
export type TableOptionsWithReactiveData<TFeatures extends TableFeatures, TData extends RowData> = { [K in keyof TableOptions<TFeatures, TData>]: K extends 'data' ? MaybeRef<ReadonlyArray<TData>> : MaybeRef<TableOptions<TFeatures, TData>[K]>; };
|
|
5
5
|
export type VueTable<TFeatures extends TableFeatures, TData extends RowData> = Table<TFeatures, TData> & {
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated Read table APIs or `table.atoms` directly inside templates,
|
|
8
|
+
* render functions, computed values, or watcher sources. Vue tracks those
|
|
9
|
+
* reads natively. This compatibility wrapper only passes atoms to its child
|
|
10
|
+
* function and adds no subscription logic.
|
|
8
11
|
*/
|
|
9
12
|
Subscribe: (props: {
|
|
10
13
|
children: (atoms: Table<TFeatures, TData>['atoms']) => VNode | Array<VNode>;
|
|
@@ -15,8 +18,8 @@ export type VueTable<TFeatures extends TableFeatures, TData extends RowData> = T
|
|
|
15
18
|
*
|
|
16
19
|
* Table options may contain Vue refs or computed values. The adapter unwraps
|
|
17
20
|
* those reactive inputs, watches them with synchronous flushing, and keeps the
|
|
18
|
-
* table options in sync.
|
|
19
|
-
*
|
|
21
|
+
* table options in sync. Read table APIs or atoms inside templates, render
|
|
22
|
+
* functions, computed values, or watcher sources to track updates.
|
|
20
23
|
*
|
|
21
24
|
* @example
|
|
22
25
|
* ```ts
|
package/dist/useTable.js
CHANGED
|
@@ -17,8 +17,8 @@ function getReactiveOptionDeps(options) {
|
|
|
17
17
|
*
|
|
18
18
|
* Table options may contain Vue refs or computed values. The adapter unwraps
|
|
19
19
|
* those reactive inputs, watches them with synchronous flushing, and keeps the
|
|
20
|
-
* table options in sync.
|
|
21
|
-
*
|
|
20
|
+
* table options in sync. Read table APIs or atoms inside templates, render
|
|
21
|
+
* functions, computed values, or watcher sources to track updates.
|
|
22
22
|
*
|
|
23
23
|
* @example
|
|
24
24
|
* ```ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/vue-table",
|
|
3
|
-
"version": "9.2.
|
|
3
|
+
"version": "9.2.7",
|
|
4
4
|
"description": "Headless UI for building powerful tables & datagrids for Vue.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@tanstack/store": "^0.11.2",
|
|
43
|
-
"@tanstack/table-core": "9.2.
|
|
43
|
+
"@tanstack/table-core": "9.2.6"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@testing-library/vue": "^8.1.0",
|
|
@@ -1,22 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: getting-started
|
|
3
|
-
description:
|
|
4
|
-
Create a Vue TanStack Table v9 table with useTable, explicit tableFeatures, stable columns/features, reactive ref or computed data, and Vue FlexRender without destructuring reactive snapshots.
|
|
3
|
+
description: Create and render Table v9 with the vue adapter. Route reusable createTableHook components, Query and Virtual integration, and framework setup; use table-state for reactive ownership.
|
|
5
4
|
metadata:
|
|
6
5
|
type: framework
|
|
7
6
|
library: '@tanstack/vue-table'
|
|
8
7
|
framework: vue
|
|
9
|
-
library_version: '9.2.
|
|
8
|
+
library_version: '9.2.7'
|
|
10
9
|
requires:
|
|
11
10
|
- '@tanstack/table-core#core'
|
|
12
|
-
- '@tanstack/table-core#table-features'
|
|
13
11
|
sources:
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
12
|
+
- TanStack/table:docs/framework/vue/guide/migrating.md
|
|
13
|
+
- TanStack/table:examples/vue/basic-use-table
|
|
14
|
+
- TanStack/table:packages/vue-table/src/index.ts
|
|
15
|
+
- TanStack/table:docs/framework/vue/guide/composable-tables.md
|
|
16
|
+
- TanStack/table:examples/vue/composable-tables
|
|
17
|
+
- TanStack/table:packages/vue-table/src/createTableHook.ts
|
|
18
|
+
- TanStack/table:examples/vue/with-tanstack-query
|
|
19
|
+
- TanStack/table:docs/framework/vue/guide/pagination.md
|
|
20
|
+
- TanStack/table:docs/framework/vue/guide/virtualization.md
|
|
21
|
+
- TanStack/table:examples/vue/virtualized-rows
|
|
22
|
+
- TanStack/table:examples/vue/virtualized-columns
|
|
23
|
+
- TanStack/table:examples/vue/virtualized-infinite-scrolling
|
|
17
24
|
---
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
# Vue Table setup and integration
|
|
27
|
+
|
|
28
|
+
Before starting, run `intent load @tanstack/table-core#core` for the shared headless model and stable-input rules.
|
|
20
29
|
|
|
21
30
|
## Setup
|
|
22
31
|
|
|
@@ -55,90 +64,21 @@ const table = useTable({ features, columns, data })
|
|
|
55
64
|
</template>
|
|
56
65
|
```
|
|
57
66
|
|
|
58
|
-
##
|
|
59
|
-
|
|
60
|
-
### Preserve Vue option shapes
|
|
61
|
-
|
|
62
|
-
`useTable` accepts refs/computed values and unwraps them while watching dependencies. Keep `data`, controlled state, and other reactive options as refs or computed values; keep static columns/features stable.
|
|
63
|
-
|
|
64
|
-
### Add a client row model explicitly
|
|
65
|
-
|
|
66
|
-
```ts
|
|
67
|
-
import {
|
|
68
|
-
createSortedRowModel,
|
|
69
|
-
rowSortingFeature,
|
|
70
|
-
sortFn_alphanumeric,
|
|
71
|
-
tableFeatures,
|
|
72
|
-
} from '@tanstack/vue-table'
|
|
73
|
-
|
|
74
|
-
const features = tableFeatures({
|
|
75
|
-
rowSortingFeature,
|
|
76
|
-
sortedRowModel: createSortedRowModel(),
|
|
77
|
-
sortFns: { alphanumeric: sortFn_alphanumeric },
|
|
78
|
-
})
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
The slot follows its prerequisite feature in the same call. Import individual `sortFn_*` built-ins and register only the ones your columns reference; the full `sortFns` registry object still works but bundles every built-in.
|
|
82
|
-
|
|
83
|
-
## Common Mistakes
|
|
84
|
-
|
|
85
|
-
### HIGH Flattening a ref into a snapshot
|
|
86
|
-
|
|
87
|
-
Wrong:
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
const table = useTable({ features, columns, data: data.value })
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Correct:
|
|
94
|
-
|
|
95
|
-
```ts
|
|
96
|
-
const table = useTable({ features, columns, data })
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
Passing `.value` captures one array instead of letting the adapter watch the ref.
|
|
67
|
+
## Essential constraints
|
|
100
68
|
|
|
101
|
-
|
|
69
|
+
Use `useTable` with a ref, computed value, or reactive getter for changing data. Passing `data.value` captures one array and loses later updates. Keep static features and columns stable; derive transformed arrays with `computed`.
|
|
102
70
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
Wrong:
|
|
106
|
-
|
|
107
|
-
```ts
|
|
108
|
-
const table = useVueTable({ data, columns, getCoreRowModel: getCoreRowModel() })
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
Correct:
|
|
112
|
-
|
|
113
|
-
```ts
|
|
114
|
-
const table = useTable({ features, columns, data })
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
V9 uses `useTable`; core processing is automatic and optional row models live in `tableFeatures`.
|
|
118
|
-
|
|
119
|
-
Source: `docs/framework/vue/guide/migrating.md`
|
|
120
|
-
|
|
121
|
-
### HIGH Assuming headless means prebuilt UI
|
|
122
|
-
|
|
123
|
-
Wrong:
|
|
124
|
-
|
|
125
|
-
```vue
|
|
126
|
-
<TanStackTable :table="table" />
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
Correct:
|
|
130
|
-
|
|
131
|
-
```vue
|
|
132
|
-
<td
|
|
133
|
-
v-for="cell in row.getAllCells()"
|
|
134
|
-
:key="cell.id"
|
|
135
|
-
><FlexRender :cell="cell" /></td>
|
|
136
|
-
```
|
|
71
|
+
Table owns models and state. The application owns markup, CSS, interactions, and accessibility. Core-only tables use `row.getAllCells()`; visibility-aware methods need `columnVisibilityFeature`. Optional state and APIs require their features. Put row-model slots after their prerequisite features in `tableFeatures()`.
|
|
137
72
|
|
|
138
|
-
|
|
73
|
+
## Load by task
|
|
139
74
|
|
|
140
|
-
|
|
75
|
+
- For repeated features, defaults, typed contexts, or component registries, read [reusable app hooks](references/create-table-hook.md).
|
|
76
|
+
- For Query-backed data, server pages, sorting, filtering, or request keys, read [TanStack Query integration](references/with-tanstack-query.md).
|
|
77
|
+
- For virtual rows, columns, dynamic measurement, or infinite scrolling, read [TanStack Virtual integration](references/with-tanstack-virtual.md).
|
|
78
|
+
- For controlled state, tracked reads, or render subscriptions, read [table state](../table-state/SKILL.md).
|
|
79
|
+
- For feature registration, missing feature APIs, or processing ownership, run `intent load @tanstack/table-core#table-features` and read only references needed by the task.
|
|
80
|
+
- For v8 code, read the [migration checklist](../migrate-v8-to-v9/SKILL.md).
|
|
141
81
|
|
|
142
|
-
## API
|
|
82
|
+
## API discovery
|
|
143
83
|
|
|
144
|
-
Inspect `node_modules/@tanstack/vue-table/dist/index.d.ts`, then
|
|
84
|
+
Inspect `node_modules/@tanstack/vue-table/dist/index.d.ts`, then the exported adapter declarations for the installed version. Inspect optional core APIs under `node_modules/@tanstack/table-core/dist/features/`.
|
package/skills/{create-table-hook/SKILL.md → getting-started/references/create-table-hook.md}
RENAMED
|
@@ -1,23 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Create a reusable Vue useAppTable/createAppColumnHelper with shared features/defaults, reactive per-table options, optional component registries, dynamic App wrappers, typed context hooks, and explicit types that break circular inference.
|
|
5
|
-
metadata:
|
|
6
|
-
type: framework
|
|
7
|
-
library: '@tanstack/vue-table'
|
|
8
|
-
framework: vue
|
|
9
|
-
library_version: '9.2.5'
|
|
10
|
-
requires:
|
|
11
|
-
- '@tanstack/table-core#core'
|
|
12
|
-
- getting-started
|
|
13
|
-
- table-state
|
|
14
|
-
sources:
|
|
15
|
-
- 'TanStack/table:docs/framework/vue/guide/composable-tables.md'
|
|
16
|
-
- 'TanStack/table:examples/vue/composable-tables'
|
|
17
|
-
- 'TanStack/table:packages/vue-table/src/createTableHook.ts'
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
This skill builds on `@tanstack/table-core#core`, `getting-started`, and `table-state`. Use it for recurring app conventions; use `useTable` for a one-off.
|
|
1
|
+
# Reusable Vue table hooks
|
|
2
|
+
|
|
3
|
+
Use this reference when multiple Vue tables share features, defaults, or registered components. Keep one-off tables on `useTable`. For controlled state or subscription changes, read [table state](../../table-state/SKILL.md).
|
|
21
4
|
|
|
22
5
|
## Setup
|
|
23
6
|
|
|
@@ -41,7 +24,7 @@ export const useTableContext: <TData extends RowData = RowData>() => VueTable<
|
|
|
41
24
|
|
|
42
25
|
The explicit exported context-hook types are important when registered components import the hook module that also imports those components.
|
|
43
26
|
|
|
44
|
-
## Core
|
|
27
|
+
## Core patterns
|
|
45
28
|
|
|
46
29
|
### Keep per-table values reactive
|
|
47
30
|
|
|
@@ -57,7 +40,7 @@ Pass refs/computed options through unchanged.
|
|
|
57
40
|
|
|
58
41
|
Render through `table.AppTable`, `table.AppCell`, or `table.AppHeader`; inside registered components call the corresponding typed context hook instead of prop drilling.
|
|
59
42
|
|
|
60
|
-
## Common
|
|
43
|
+
## Common mistakes
|
|
61
44
|
|
|
62
45
|
### HIGH Creating circular inferred exports
|
|
63
46
|
|
|
@@ -72,7 +55,7 @@ export const { useAppTable, useTableContext } = createTableHook({
|
|
|
72
55
|
Correct:
|
|
73
56
|
|
|
74
57
|
```ts
|
|
75
|
-
const hook = createTableHook({ tableComponents: { Pager } })
|
|
58
|
+
const hook = createTableHook({ features, tableComponents: { Pager } })
|
|
76
59
|
export const useTableContext: <TData extends RowData = RowData>() => VueTable<
|
|
77
60
|
typeof features,
|
|
78
61
|
TData
|
|
@@ -119,28 +102,18 @@ The typed context exists only below the corresponding dynamic wrapper.
|
|
|
119
102
|
|
|
120
103
|
Source: `packages/vue-table/src/createTableHook.ts`
|
|
121
104
|
|
|
122
|
-
###
|
|
123
|
-
|
|
124
|
-
Wrong:
|
|
125
|
-
|
|
126
|
-
```tsx
|
|
127
|
-
<table.Subscribe>
|
|
128
|
-
{(atoms) => <Pager page={atoms.pagination.get()} />}
|
|
129
|
-
</table.Subscribe>
|
|
130
|
-
```
|
|
105
|
+
### Read state in the consuming component
|
|
131
106
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
```tsx
|
|
135
|
-
<table.Subscribe
|
|
136
|
-
children={(atoms) => <Pager page={atoms.pagination.get()} />}
|
|
137
|
-
/>
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
Vue’s adapter expects an explicit `children` prop in JSX.
|
|
107
|
+
Read table APIs and atoms inside the component's template or render function. Vue tracks those reads natively. Use a child component when you need a separate render boundary; `table.Subscribe` is deprecated.
|
|
141
108
|
|
|
142
109
|
Source: `packages/vue-table/src/useTable.ts`
|
|
143
110
|
|
|
144
|
-
## API
|
|
111
|
+
## API discovery
|
|
145
112
|
|
|
146
113
|
Inspect `node_modules/@tanstack/vue-table/dist/createTableHook.d.ts` for the returned helpers, wrapper props, registry types, and context contracts.
|
|
114
|
+
|
|
115
|
+
## Sources
|
|
116
|
+
|
|
117
|
+
- `TanStack/table:docs/framework/vue/guide/composable-tables.md`
|
|
118
|
+
- `TanStack/table:examples/vue/composable-tables`
|
|
119
|
+
- `TanStack/table:packages/vue-table/src/createTableHook.ts`
|
package/skills/{with-tanstack-query/SKILL.md → getting-started/references/with-tanstack-query.md}
RENAMED
|
@@ -1,22 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Compose reactive Vue Query keys and results with Vue Table manual row processing, refs/computed state, server counts, and already-processed pages without duplicating query data into a drifting local ref.
|
|
5
|
-
metadata:
|
|
6
|
-
type: composition
|
|
7
|
-
library: '@tanstack/vue-table'
|
|
8
|
-
framework: vue
|
|
9
|
-
library_version: '9.2.5'
|
|
10
|
-
requires:
|
|
11
|
-
- '@tanstack/table-core#client-vs-server'
|
|
12
|
-
- getting-started
|
|
13
|
-
- table-state
|
|
14
|
-
sources:
|
|
15
|
-
- 'TanStack/table:examples/vue/with-tanstack-query'
|
|
16
|
-
- 'TanStack/table:docs/framework/vue/guide/pagination.md'
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
This skill builds on `@tanstack/table-core#client-vs-server`, `getting-started`, and `table-state`. Name each client- and server-owned processing stage first.
|
|
1
|
+
# Vue Table with TanStack Query
|
|
2
|
+
|
|
3
|
+
Use this reference when Query owns server data for a Vue table. Read [table state](../../table-state/SKILL.md) for reactive ownership. Run `intent load @tanstack/table-core#table-features` and read its client/server reference before choosing manual processing stages. Query fetches rows already processed by every server-owned stage; manual flags only bypass Table processing.
|
|
20
4
|
|
|
21
5
|
## Setup
|
|
22
6
|
|
|
@@ -29,6 +13,8 @@ import {
|
|
|
29
13
|
useTable,
|
|
30
14
|
} from '@tanstack/vue-table'
|
|
31
15
|
|
|
16
|
+
const features = tableFeatures({ rowPaginationFeature })
|
|
17
|
+
const emptyRows: Array<{ name: string }> = []
|
|
32
18
|
const pagination = ref({ pageIndex: 0, pageSize: 20 })
|
|
33
19
|
const query = useQuery(() => ({
|
|
34
20
|
queryKey: ['people', pagination.value.pageIndex, pagination.value.pageSize],
|
|
@@ -38,11 +24,11 @@ const query = useQuery(() => ({
|
|
|
38
24
|
).then((r) => r.json()),
|
|
39
25
|
placeholderData: keepPreviousData,
|
|
40
26
|
}))
|
|
41
|
-
const data = computed(() => query.data.value?.rows ??
|
|
27
|
+
const data = computed(() => query.data.value?.rows ?? emptyRows)
|
|
42
28
|
const rowCount = computed(() => query.data.value?.rowCount ?? 0)
|
|
43
29
|
const state = computed(() => ({ pagination: pagination.value }))
|
|
44
30
|
const table = useTable({
|
|
45
|
-
features
|
|
31
|
+
features,
|
|
46
32
|
columns,
|
|
47
33
|
data,
|
|
48
34
|
rowCount,
|
|
@@ -55,7 +41,7 @@ const table = useTable({
|
|
|
55
41
|
})
|
|
56
42
|
```
|
|
57
43
|
|
|
58
|
-
## Core
|
|
44
|
+
## Core patterns
|
|
59
45
|
|
|
60
46
|
### Keep query dependencies reactive
|
|
61
47
|
|
|
@@ -65,7 +51,7 @@ Use the Vue Query options function and read refs inside it. Include every manual
|
|
|
65
51
|
|
|
66
52
|
Expose result fields as computed refs. Introduce a second local data ref only for an explicit editing workflow with a cache-write policy.
|
|
67
53
|
|
|
68
|
-
## Common
|
|
54
|
+
## Common mistakes
|
|
69
55
|
|
|
70
56
|
### HIGH Unwrapping before query construction
|
|
71
57
|
|
|
@@ -97,7 +83,7 @@ const rows = ref(query.data.value?.rows ?? [])
|
|
|
97
83
|
Correct:
|
|
98
84
|
|
|
99
85
|
```ts
|
|
100
|
-
const rows = computed(() => query.data.value?.rows ??
|
|
86
|
+
const rows = computed(() => query.data.value?.rows ?? emptyRows)
|
|
101
87
|
```
|
|
102
88
|
|
|
103
89
|
A one-time copy drifts from subsequent cache results.
|
|
@@ -122,6 +108,11 @@ One returned page cannot tell Table how many pages the server has.
|
|
|
122
108
|
|
|
123
109
|
Source: `docs/framework/vue/guide/pagination.md`
|
|
124
110
|
|
|
125
|
-
## API
|
|
111
|
+
## API discovery
|
|
112
|
+
|
|
113
|
+
Inspect installed `@tanstack/vue-table/dist/useTable.d.ts`, installed `@tanstack/vue-query/dist/`, and the relevant manual installed Table feature declarations for exact option types.
|
|
114
|
+
|
|
115
|
+
## Sources
|
|
126
116
|
|
|
127
|
-
|
|
117
|
+
- `TanStack/table:examples/vue/with-tanstack-query`
|
|
118
|
+
- `TanStack/table:docs/framework/vue/guide/pagination.md`
|
|
@@ -1,24 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Virtualize Vue Table final row or column models with reactive counts and scroll targets, stable keys, measurement, spacer geometry, sticky CSS, grid/flex widths, and infinite server data.
|
|
5
|
-
metadata:
|
|
6
|
-
type: composition
|
|
7
|
-
library: '@tanstack/vue-table'
|
|
8
|
-
framework: vue
|
|
9
|
-
library_version: '9.2.5'
|
|
10
|
-
requires:
|
|
11
|
-
- '@tanstack/table-core#core'
|
|
12
|
-
- getting-started
|
|
13
|
-
- table-state
|
|
14
|
-
sources:
|
|
15
|
-
- 'TanStack/table:docs/framework/vue/guide/virtualization.md'
|
|
16
|
-
- 'TanStack/table:examples/vue/virtualized-rows'
|
|
17
|
-
- 'TanStack/table:examples/vue/virtualized-columns'
|
|
18
|
-
- 'TanStack/table:examples/vue/virtualized-infinite-scrolling'
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
This skill builds on `@tanstack/table-core#core`, `getting-started`, and `table-state`. Virtual consumes final Table models; it is not registered in `tableFeatures`.
|
|
1
|
+
# Vue Table with TanStack Virtual
|
|
2
|
+
|
|
3
|
+
Use this reference when virtualizing Vue table rows or columns. Virtual consumes the final Table model in the renderer; it is not a Table feature. For reactive model or subscription problems, read [table state](../../table-state/SKILL.md). Register `columnSizingFeature` before calling sizing APIs, and `columnVisibilityFeature` before visibility-aware APIs.
|
|
22
4
|
|
|
23
5
|
## Setup
|
|
24
6
|
|
|
@@ -41,7 +23,7 @@ const virtualRows = computed(() => rowVirtualizer.value.getVirtualItems())
|
|
|
41
23
|
const totalSize = computed(() => rowVirtualizer.value.getTotalSize())
|
|
42
24
|
```
|
|
43
25
|
|
|
44
|
-
## Core
|
|
26
|
+
## Core patterns
|
|
45
27
|
|
|
46
28
|
### Derive from current visible models
|
|
47
29
|
|
|
@@ -55,7 +37,7 @@ Give the scroll container a bounded height and positioning context, create a spa
|
|
|
55
37
|
|
|
56
38
|
Fetch near the last virtual item only while `totalFetched < serverRowCount` and no request is active. Manual sorting means the server must return the sorted order and a sort change normally resets pages.
|
|
57
39
|
|
|
58
|
-
## Common
|
|
40
|
+
## Common mistakes
|
|
59
41
|
|
|
60
42
|
### HIGH Passing a plain options snapshot
|
|
61
43
|
|
|
@@ -111,6 +93,13 @@ Virtual provides measurements, not spacer layout, transforms, sticky positioning
|
|
|
111
93
|
|
|
112
94
|
Source: `examples/vue/virtualized-columns/src/App.vue`
|
|
113
95
|
|
|
114
|
-
## API
|
|
96
|
+
## API discovery
|
|
115
97
|
|
|
116
98
|
Inspect installed `@tanstack/vue-table/dist/` and `@tanstack/vue-virtual/dist/`; use the maintained Vue examples for exact row, column, and infinite layout combinations.
|
|
99
|
+
|
|
100
|
+
## Sources
|
|
101
|
+
|
|
102
|
+
- `TanStack/table:docs/framework/vue/guide/virtualization.md`
|
|
103
|
+
- `TanStack/table:examples/vue/virtualized-rows`
|
|
104
|
+
- `TanStack/table:examples/vue/virtualized-columns`
|
|
105
|
+
- `TanStack/table:examples/vue/virtualized-infinite-scrolling`
|
|
@@ -1,185 +1,48 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: migrate-v8-to-v9
|
|
3
|
-
description:
|
|
4
|
-
Complete Vue v8-to-v9 migration reference: useTable, explicit features and row-model slots, ref/atom state, FlexRender shorthand, prototype methods, type generics, sorting, sizing, selection, and logical pinning.
|
|
3
|
+
description: Migrate vue Table v8 to v9. Audit framework construction, rendering, state, and app hooks, with shared API changes in the core migration skill.
|
|
5
4
|
metadata:
|
|
6
5
|
type: lifecycle
|
|
7
6
|
library: '@tanstack/vue-table'
|
|
8
7
|
framework: vue
|
|
9
|
-
library_version: '9.2.
|
|
8
|
+
library_version: '9.2.7'
|
|
10
9
|
requires:
|
|
11
10
|
- '@tanstack/table-core#migrate-v8-to-v9'
|
|
12
|
-
- getting-started
|
|
13
|
-
- table-state
|
|
14
11
|
sources:
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
12
|
+
- TanStack/table:docs/framework/vue/guide/migrating.md
|
|
13
|
+
- TanStack/table:packages/vue-table/src/index.ts
|
|
14
|
+
- TanStack/table:examples/vue/basic-use-table
|
|
18
15
|
---
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
# Vue v8-to-v9 migration checklist
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
## Recommended Migration Order
|
|
25
|
-
|
|
26
|
-
1. Replace `useVueTable` with `useTable` while preserving reactive inputs.
|
|
27
|
-
2. Define explicit features, then move row models and registries into `tableFeatures`.
|
|
28
|
-
3. Update state reads, controlled ownership, and rendering.
|
|
29
|
-
4. Apply every shared API and type rename below.
|
|
30
|
-
5. Use `stockFeatures` only as a temporary audit bridge; explicit features are the production target.
|
|
31
|
-
|
|
32
|
-
```ts
|
|
33
|
-
const features = tableFeatures({
|
|
34
|
-
rowSortingFeature,
|
|
35
|
-
sortedRowModel: createSortedRowModel(),
|
|
36
|
-
sortFns: { alphanumeric: sortFn_alphanumeric },
|
|
37
|
-
})
|
|
38
|
-
const data = ref(makeData())
|
|
39
|
-
const table = useTable({ features, columns, data })
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Construction and Feature Registration
|
|
43
|
-
|
|
44
|
-
| v8 | v9 |
|
|
45
|
-
| -------------------------------------------- | ---------------------------------------------------------- |
|
|
46
|
-
| `useVueTable(options)` | `useTable(options)` |
|
|
47
|
-
| All features bundled | Required `features: tableFeatures({...})` |
|
|
48
|
-
| `getCoreRowModel()` option | Remove; core row model is automatic |
|
|
49
|
-
| `get*RowModel()` table options | `create*RowModel()` slots in `tableFeatures` |
|
|
50
|
-
| `sortingFns` table option | `sortFns` feature slot |
|
|
51
|
-
| `filterFns` / `aggregationFns` table options | Same-named feature slots |
|
|
52
|
-
| Top-level `onStateChange` | Per-slice callbacks, external atoms, or store subscription |
|
|
53
|
-
|
|
54
|
-
Available feature imports are `cellSelectionFeature`, `columnFilteringFeature`, `globalFilteringFeature`, `rowSortingFeature`, `rowPaginationFeature`, `rowSelectionFeature`, `rowExpandingFeature`, `rowPinningFeature`, `columnPinningFeature`, `columnVisibilityFeature`, `columnOrderingFeature`, `columnSizingFeature`, `columnResizingFeature`, `rowAggregationFeature`, `columnGroupingFeature`, and `columnFacetingFeature`. APIs are feature-gated. Put every feature before its dependent slot in the same `tableFeatures` call. Aggregation is independent from grouping: register `rowAggregationFeature` for aggregation APIs and add `columnGroupingFeature` only for grouped rows.
|
|
55
|
-
|
|
56
|
-
### Row-model mapping
|
|
57
|
-
|
|
58
|
-
| v8 option | v9 slot and factory |
|
|
59
|
-
| -------------------------- | ------------------------------------------------------------------- |
|
|
60
|
-
| `getFilteredRowModel()` | `filteredRowModel: createFilteredRowModel()` after column filtering |
|
|
61
|
-
| `getSortedRowModel()` | `sortedRowModel: createSortedRowModel()` after row sorting |
|
|
62
|
-
| `getPaginationRowModel()` | `paginatedRowModel: createPaginatedRowModel()` after pagination |
|
|
63
|
-
| `getExpandedRowModel()` | `expandedRowModel: createExpandedRowModel()` after expanding |
|
|
64
|
-
| `getGroupedRowModel()` | `groupedRowModel: createGroupedRowModel()` after grouping |
|
|
65
|
-
| `getFacetedRowModel()` | `facetedRowModel: createFacetedRowModel()` after faceting |
|
|
66
|
-
| `getFacetedMinMaxValues()` | `facetedMinMaxValues: createFacetedMinMaxValues()` |
|
|
67
|
-
| `getFacetedUniqueValues()` | `facetedUniqueValues: createFacetedUniqueValues()` |
|
|
68
|
-
|
|
69
|
-
Factories take no arguments. Register `filterFns`, `sortFns`, and `aggregationFns` as sibling feature slots holding individually imported built-ins (`filterFn_includesString`, `sortFn_alphanumeric`, `aggregationFn_sum`) under their conventional keys. The full registry objects still work but bundle every built-in.
|
|
70
|
-
|
|
71
|
-
## Vue State Migration
|
|
72
|
-
|
|
73
|
-
- Pass a `ref` or `computed` as `data`; the adapter unwraps and syncs it. Do not pass `data.value`, which is only a snapshot. A getter returning `data.value` is also supported.
|
|
74
|
-
- `table.getState().sorting` becomes the narrow `table.atoms.sorting.get()`. Use `table.store.get()` only for a full snapshot/debug output.
|
|
75
|
-
- Wrap atom reads in Vue `computed` when deriving template values.
|
|
76
|
-
- In JSX/render functions, `table.Subscribe` provides a fine-grained boundary. Pass the callback as the explicit `children` prop because Vue JSX element children become slots.
|
|
77
|
-
- Controlled refs need getter-backed state slices plus per-slice callbacks that resolve value-or-function `Updater`s.
|
|
78
|
-
- The top-level `onStateChange` is removed. Use per-slice callbacks, external atoms, or `table.store.subscribe` to observe everything.
|
|
79
|
-
- External atoms come from `@tanstack/vue-store` and are supplied through `atoms`. Never provide both `atoms.pagination` and `state.pagination`.
|
|
80
|
-
- `table.baseAtoms` is internal writable state; prefer feature APIs or external atoms.
|
|
81
|
-
|
|
82
|
-
## Rendering and Composition
|
|
83
|
-
|
|
84
|
-
| v8 | v9 target |
|
|
85
|
-
| -------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
86
|
-
| `<FlexRender :render="cell.column.columnDef.cell" :props="cell.getContext()" />` | `<FlexRender :cell="cell" />` |
|
|
87
|
-
| Manual header/footer render props | `<FlexRender :header="header" />` / `:footer="footer"` |
|
|
88
|
-
| Repeated raw options | `tableOptions(...)` composition |
|
|
89
|
-
| Repeated table conventions | `createTableHook({ features, ... })` and pre-bound helpers |
|
|
90
|
-
|
|
91
|
-
The old `render`/`props` FlexRender shape still compiles, but shorthand is the migration target. `createTableHook` is optional and intended for application-wide conventions.
|
|
92
|
-
|
|
93
|
-
## Complete Shared Breaking-Change Map
|
|
94
|
-
|
|
95
|
-
### Instance methods
|
|
19
|
+
Before starting, run `intent load @tanstack/table-core#migrate-v8-to-v9`. Audit its entire shared checklist and read the detailed core mappings for APIs present in the application. This checklist adds the Vue-specific changes.
|
|
96
20
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
### Logical column pinning
|
|
100
|
-
|
|
101
|
-
V9 has no `left`/`right` aliases.
|
|
102
|
-
|
|
103
|
-
| old | new |
|
|
104
|
-
| -------------------------------------------------------------- | ------------------------------------------------------------- |
|
|
105
|
-
| `columnPinning.left` / `.right` | `.start` / `.end` |
|
|
106
|
-
| `column.pin('left' \| 'right')` | `column.pin('start' \| 'end')` |
|
|
107
|
-
| `getIsPinned() === 'left' \| 'right'` | `'start' \| 'end'` |
|
|
108
|
-
| `row.getLeftVisibleCells()` / `getRightVisibleCells()` | `getStartVisibleCells()` / `getEndVisibleCells()` |
|
|
109
|
-
| `getLeftHeaderGroups()` / `getRightHeaderGroups()` | `getStartHeaderGroups()` / `getEndHeaderGroups()` |
|
|
110
|
-
| `getLeftFooterGroups()` / `getRightFooterGroups()` | `getStartFooterGroups()` / `getEndFooterGroups()` |
|
|
111
|
-
| `getLeftFlatHeaders()` / `getRightFlatHeaders()` | `getStartFlatHeaders()` / `getEndFlatHeaders()` |
|
|
112
|
-
| `getLeftLeafHeaders()` / `getRightLeafHeaders()` | `getStartLeafHeaders()` / `getEndLeafHeaders()` |
|
|
113
|
-
| `getLeftLeafColumns()` / `getRightLeafColumns()` | `getStartLeafColumns()` / `getEndLeafColumns()` |
|
|
114
|
-
| `getLeftVisibleLeafColumns()` / `getRightVisibleLeafColumns()` | `getStartVisibleLeafColumns()` / `getEndVisibleLeafColumns()` |
|
|
115
|
-
| `getLeftTotalSize()` / `getRightTotalSize()` | `getStartTotalSize()` / `getEndTotalSize()` |
|
|
116
|
-
| `column.getStart('left')` | `column.getStart('start')` |
|
|
117
|
-
| `column.getAfter('right')` | `column.getAfter('end')` |
|
|
118
|
-
| `column.getIndex('left' \| 'right')` | `column.getIndex('start' \| 'end')` |
|
|
119
|
-
|
|
120
|
-
Use CSS `inset-inline-start`/`inset-inline-end`; logical names do not automatically set DOM direction. `columnResizeDirection` is unchanged.
|
|
121
|
-
|
|
122
|
-
### Pinning, sizing, and resizing
|
|
123
|
-
|
|
124
|
-
- `enablePinning` splits into `enableColumnPinning` and `enableRowPinning`.
|
|
125
|
-
- Interactive resizing requires `columnSizingFeature` plus `columnResizingFeature`; fixed sizing needs only the former.
|
|
126
|
-
- `columnSizingInfo` becomes `columnResizing`.
|
|
127
|
-
- `setColumnSizingInfo()` becomes `setColumnResizing()`.
|
|
128
|
-
- `onColumnSizingInfoChange` becomes `onColumnResizingChange`.
|
|
129
|
-
|
|
130
|
-
### Sorting, rows, and selection
|
|
131
|
-
|
|
132
|
-
| v8 | v9 |
|
|
133
|
-
| ------------------------------ | ----------------------------- |
|
|
134
|
-
| `sortingFn` | `sortFn` |
|
|
135
|
-
| `sortingFns` | `sortFns` |
|
|
136
|
-
| `getSortingFn()` | `getSortFn()` |
|
|
137
|
-
| `getAutoSortingFn()` | `getAutoSortFn()` |
|
|
138
|
-
| `SortingFn` / `SortingFns` | `SortFn` / `SortFns` |
|
|
139
|
-
| `row._getAllCellsByColumnId()` | `row.getAllCellsByColumnId()` |
|
|
140
|
-
|
|
141
|
-
Other `_`-prefixed internals are removed, including `_getPinnedRows`, `_getFacetedRowModel`, `_getFacetedMinMaxValues`, and `_getFacetedUniqueValues`.
|
|
142
|
-
|
|
143
|
-
`getIsSomeRowsSelected()` and `getIsSomePageRowsSelected()` now mean at least one, including all. Indeterminate UI must also check `!getIsAllRowsSelected()` or `!getIsAllPageRowsSelected()`.
|
|
144
|
-
|
|
145
|
-
## TypeScript Migration
|
|
146
|
-
|
|
147
|
-
- Add `TFeatures` first: `ColumnDef<typeof features, Person>`, `Column<typeof features, Person>`, `Row<typeof features, Person>`, `Table<typeof features, Person>`.
|
|
148
|
-
- Replace `createColumnHelper<Person>()` with `createColumnHelper<typeof features, Person>()`; use `columnHelper.columns([...])` for nested-array inference.
|
|
149
|
-
- Use `StockFeatures` when `stockFeatures` is the configuration.
|
|
150
|
-
- Existing `TableMeta`/`ColumnMeta` declaration merging must add `TFeatures` first. Prefer per-table `tableMeta`/`columnMeta: metaHelper<...>()` slots.
|
|
151
|
-
- Replace global `FilterFns`, `SortFns`, `AggregationFns`, and `FilterMeta` augmentation with registry slots and `filterMeta: metaHelper<...>()`; registered keys become valid strings in column defs.
|
|
152
|
-
- `RowData` is restricted to records or arrays; prefer explicit object row types.
|
|
153
|
-
|
|
154
|
-
## Common Migration Failures
|
|
155
|
-
|
|
156
|
-
### HIGH: Renaming only the composable
|
|
157
|
-
|
|
158
|
-
`useTable({ getSortedRowModel: ... })` is still a v8 configuration. Move the row model and its prerequisite feature into `tableFeatures`.
|
|
159
|
-
|
|
160
|
-
### HIGH: Unwrapping refs before useTable
|
|
21
|
+
Framework prerequisite: Vue 3.2 or newer (`vue >=3.2`).
|
|
161
22
|
|
|
162
|
-
|
|
23
|
+
## Adapter audit
|
|
163
24
|
|
|
164
|
-
|
|
25
|
+
- [ ] Replace `useVueTable` with `useTable` and preserve ref/computed/getter inputs.
|
|
26
|
+
- [ ] Keep features and columns stable, configure explicit features/row-model slots, and complete the shared core checklist.
|
|
27
|
+
- [ ] Replace `getState()` with tracked atom reads or intentional whole-store reads. Use `computed` for derived template values.
|
|
28
|
+
- [ ] Pair controlled reactive values with callbacks that resolve both updater forms, or supply stable Vue Store atoms. Remove global `onStateChange`.
|
|
29
|
+
- [ ] Replace deprecated `table.Subscribe` calls with native reactive reads. Use a child component when you need to preserve a separate component render boundary.
|
|
30
|
+
- [ ] Adopt FlexRender cell/header/footer shorthand; the old render/props shape remains supported.
|
|
31
|
+
- [ ] Use `tableOptions` or `createTableHook` only for repeated conventions and explicit context-hook export types when needed to break circular inference.
|
|
165
32
|
|
|
166
|
-
|
|
33
|
+
## Load the affected details
|
|
167
34
|
|
|
168
|
-
|
|
35
|
+
When the audit finds old Vue construction, state, rendering, or app-hook code, read [adapter migration details](references/adapter-migration.md) before editing it. For a replacement render scaffold, read [getting started](../getting-started/SKILL.md). For controlled or stale state after migration, read [table state](../table-state/SKILL.md).
|
|
169
36
|
|
|
170
|
-
|
|
37
|
+
Shared pinning, sizing, sorting, selection, prototype-method, type, and registry changes stay in the core migration references. Renaming `useVueTable` alone does not complete the migration.
|
|
171
38
|
|
|
172
|
-
##
|
|
39
|
+
## Verify the migration
|
|
173
40
|
|
|
174
|
-
- [ ]
|
|
175
|
-
- [ ]
|
|
176
|
-
- [ ]
|
|
177
|
-
- [ ]
|
|
178
|
-
- [ ] FlexRender shorthand is adopted where applicable.
|
|
179
|
-
- [ ] Prototype methods, pinning, sizing/resizing, sorting, row, and selection changes are audited.
|
|
180
|
-
- [ ] Helpers, types, meta, registries, and `RowData` use v9 shapes.
|
|
181
|
-
- [ ] Temporary `stockFeatures` usage has an explicit removal plan.
|
|
41
|
+
- [ ] Type-check against the installed v9 adapter and exercise every enabled client/manual feature flow.
|
|
42
|
+
- [ ] Verify external state writes, reactive data replacement, and the framework rendering paths changed above.
|
|
43
|
+
- [ ] Complete the core checklist, including layout and selection behavior when those features are used.
|
|
44
|
+
- [ ] Replace temporary `stockFeatures` when the target is explicit feature tree-shaking.
|
|
182
45
|
|
|
183
|
-
## API
|
|
46
|
+
## API discovery
|
|
184
47
|
|
|
185
|
-
Inspect `node_modules/@tanstack/vue-table/dist/index.d.ts` and
|
|
48
|
+
Inspect `node_modules/@tanstack/vue-table/dist/index.d.ts` and the exported adapter declarations. Use `node_modules/@tanstack/table-core/dist/index.d.ts` for shared APIs.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Vue adapter migration details
|
|
2
|
+
|
|
3
|
+
Read when replacing Vue table construction, reactive state, rendering, or reusable app hooks. First complete the shared checklist from `intent load @tanstack/table-core#migrate-v8-to-v9`; its references own shared feature, method, and TypeScript mappings.
|
|
4
|
+
|
|
5
|
+
## Replace `useVueTable` with `useTable`
|
|
6
|
+
|
|
7
|
+
Preserve reactive option wrappers while replacing the composable. `data: data.value` captures one array; pass the ref or a getter returning its current value.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const features = tableFeatures({
|
|
11
|
+
rowSortingFeature,
|
|
12
|
+
sortedRowModel: createSortedRowModel(),
|
|
13
|
+
sortFns: { alphanumeric: sortFn_alphanumeric },
|
|
14
|
+
})
|
|
15
|
+
const data = ref(makeData())
|
|
16
|
+
const table = useTable({ features, columns, data })
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Vue state migration
|
|
20
|
+
|
|
21
|
+
- Pass a `ref` or `computed` as `data`; the adapter unwraps and syncs it. Do not pass `data.value`, which is only a snapshot. A getter returning `data.value` is also supported.
|
|
22
|
+
- `table.getState().sorting` becomes the narrow `table.atoms.sorting.get()`. Use `table.store.get()` only for a full snapshot/debug output.
|
|
23
|
+
- Wrap atom reads in Vue `computed` when deriving template values.
|
|
24
|
+
- Replace deprecated `table.Subscribe` calls with direct atom reads inside templates, render functions, computed getters, or watcher sources. If it was used as a component to isolate rendering, move the reads into a child component.
|
|
25
|
+
- Controlled refs need getter-backed state slices plus per-slice callbacks that resolve value-or-function `Updater`s.
|
|
26
|
+
- The top-level `onStateChange` is removed. Use per-slice callbacks, external atoms, or `table.store.subscribe` to observe everything.
|
|
27
|
+
- External atoms come from `@tanstack/vue-store` and are supplied through `atoms`. Never provide both `atoms.pagination` and `state.pagination`.
|
|
28
|
+
- `table.baseAtoms` is internal writable state; prefer feature APIs or external atoms.
|
|
29
|
+
|
|
30
|
+
## Rendering and composition
|
|
31
|
+
|
|
32
|
+
| v8 | v9 target |
|
|
33
|
+
| -------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
34
|
+
| `<FlexRender :render="cell.column.columnDef.cell" :props="cell.getContext()" />` | `<FlexRender :cell="cell" />` |
|
|
35
|
+
| Manual header/footer render props | `<FlexRender :header="header" />` / `:footer="footer"` |
|
|
36
|
+
| Repeated raw options | `tableOptions(...)` composition |
|
|
37
|
+
| Repeated table conventions | `createTableHook({ features, ... })` and pre-bound helpers |
|
|
38
|
+
|
|
39
|
+
The old `render`/`props` FlexRender shape still compiles, but shorthand is the migration target. `createTableHook` is optional and intended for application-wide conventions.
|
|
40
|
+
|
|
41
|
+
For detailed controlled wiring or tracking failures, read [table state](../../table-state/SKILL.md). For reusable contexts or components, read [app-hook composition](../../getting-started/references/create-table-hook.md).
|
|
42
|
+
|
|
43
|
+
## API discovery
|
|
44
|
+
|
|
45
|
+
Inspect `node_modules/@tanstack/vue-table/dist/index.d.ts` and its exported declarations for construction, rendering, and app hooks.
|
|
46
|
+
|
|
47
|
+
## Sources
|
|
48
|
+
|
|
49
|
+
- `TanStack/table:docs/framework/vue/guide/migrating.md`
|
|
50
|
+
- `TanStack/table:packages/vue-table/src/index.ts`
|
|
51
|
+
- `TanStack/table:examples/vue/basic-use-table`
|
|
@@ -1,34 +1,32 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: table-state
|
|
3
|
-
description:
|
|
4
|
-
Read Vue-backed table.atoms/store in templates, computed, watch, or table.Subscribe; own slices with refs/computed or external Vue Store atoms; and apply updater callbacks while preserving reactive option shapes.
|
|
3
|
+
description: Read and control Table v9 state in vue. Use for tracked reads, subscriptions, controlled slices, and framework-specific reactive boundaries.
|
|
5
4
|
metadata:
|
|
6
5
|
type: framework
|
|
7
6
|
library: '@tanstack/vue-table'
|
|
8
7
|
framework: vue
|
|
9
|
-
library_version: '9.2.
|
|
8
|
+
library_version: '9.2.7'
|
|
10
9
|
requires:
|
|
11
|
-
- '@tanstack/table-core#
|
|
12
|
-
- getting-started
|
|
10
|
+
- '@tanstack/table-core#table-state'
|
|
13
11
|
sources:
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
12
|
+
- TanStack/table:docs/framework/vue/guide/table-state.md
|
|
13
|
+
- TanStack/table:examples/vue/basic-external-state
|
|
14
|
+
- TanStack/table:packages/vue-table/src/useTable.ts
|
|
17
15
|
---
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
# Vue table state
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
Before starting, run `intent load @tanstack/table-core#table-state` for shared ownership, initialization, updates, and resets.
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
## Read reactive state
|
|
24
22
|
|
|
25
|
-
- `table.
|
|
26
|
-
- `table.atoms` are readonly derived atoms for the active owner of each registered slice.
|
|
27
|
-
- `table.store` combines those atoms into one readonly flat store.
|
|
23
|
+
Vue-backed atom reads track dependencies inside templates, `computed`, `watch`, or a render boundary. `const page = table.atoms.pagination.get()` outside tracking captures a snapshot. Keep reactive option inputs as refs, computed values, or getters; passing `.value` once breaks later synchronization.
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
`table.Subscribe` is deprecated. Read table APIs or atoms directly inside templates, render functions, computed getters, or watcher sources. Use a child component when reads need a separate component render boundary.
|
|
30
26
|
|
|
31
|
-
##
|
|
27
|
+
## Control a slice
|
|
28
|
+
|
|
29
|
+
Keep features and columns stable. Preserve both the reactive value and its matching callback:
|
|
32
30
|
|
|
33
31
|
```ts
|
|
34
32
|
import { computed, ref } from 'vue'
|
|
@@ -36,156 +34,32 @@ import {
|
|
|
36
34
|
rowPaginationFeature,
|
|
37
35
|
tableFeatures,
|
|
38
36
|
useTable,
|
|
37
|
+
type PaginationState,
|
|
38
|
+
type Updater,
|
|
39
39
|
} from '@tanstack/vue-table'
|
|
40
40
|
|
|
41
41
|
const features = tableFeatures({ rowPaginationFeature })
|
|
42
|
-
const data = ref([{ name: 'Ada' }])
|
|
43
42
|
const columns = [{ accessorKey: 'name' }]
|
|
44
|
-
const
|
|
45
|
-
const pageIndex = computed(() => table.atoms.pagination.get().pageIndex)
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Internal state is usually enough. Atom reads are reactive only when Vue evaluates them in a tracked template, computed, watch, or render boundary.
|
|
49
|
-
|
|
50
|
-
## Core Patterns
|
|
51
|
-
|
|
52
|
-
### Control a slice without losing updater semantics
|
|
53
|
-
|
|
54
|
-
```ts
|
|
55
|
-
import { computed, ref } from 'vue'
|
|
56
|
-
import type { PaginationState } from '@tanstack/vue-table'
|
|
57
|
-
|
|
43
|
+
const data = ref([{ name: 'Ada' }])
|
|
58
44
|
const pagination = ref<PaginationState>({ pageIndex: 0, pageSize: 20 })
|
|
59
|
-
const
|
|
60
|
-
const onPaginationChange = (
|
|
61
|
-
next: PaginationState | ((old: PaginationState) => PaginationState),
|
|
62
|
-
) => {
|
|
63
|
-
pagination.value = typeof next === 'function' ? next(pagination.value) : next
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Pass `state: controlledState` and `onPaginationChange` to `useTable`.
|
|
68
|
-
|
|
69
|
-
### Use Subscribe as a render boundary
|
|
70
|
-
|
|
71
|
-
```tsx
|
|
72
|
-
table.Subscribe({
|
|
73
|
-
children: (atoms) => <span>{atoms.pagination.get().pageIndex + 1}</span>,
|
|
74
|
-
})
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
In Vue JSX, `children` is an explicit prop, not a slot child.
|
|
78
|
-
|
|
79
|
-
## Choose State Ownership
|
|
80
|
-
|
|
81
|
-
Use exactly one owner per slice:
|
|
82
|
-
|
|
83
|
-
- Prefer internal state and feature methods for table-local behavior.
|
|
84
|
-
- Use `initialState` for starting/reset values; changing it later does not reset current state.
|
|
85
|
-
- Prefer a stable `@tanstack/vue-store` atom in `atoms` for cross-system ownership. Feature APIs update it directly, so omit `on[State]Change`.
|
|
86
|
-
- Use a ref/computed `state` value plus the matching callback for simple controlled state. Preserve the reactive wrapper and resolve raw values and updater functions.
|
|
87
|
-
|
|
88
|
-
External atoms take precedence over external `state`, which syncs into the internal base atom. Do not configure multiple owners. The global v8 `onStateChange` option is gone; observe `table.store` if all state changes matter.
|
|
89
|
-
|
|
90
|
-
## Initialize, Update, and Reset
|
|
91
|
-
|
|
92
|
-
Use feature methods such as `setSorting`, `nextPage`, `toggleVisibility`, and `toggleSelected`. Direct `baseAtoms` writes are a rare escape hatch for internally owned state; write the external atom when it owns the slice.
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
table.resetSorting()
|
|
96
|
-
table.resetPagination()
|
|
97
|
-
table.resetPagination(true)
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Feature resets use `table.initialState` unless `true` requests the feature default and can update external owners. Core `table.reset()` only resets internal base atoms. Use slice types such as `PaginationState`; use `TableState<typeof features>` for the complete feature-inferred state.
|
|
101
|
-
|
|
102
|
-
## Common Mistakes
|
|
103
|
-
|
|
104
|
-
### HIGH Reading an untracked snapshot
|
|
105
|
-
|
|
106
|
-
Wrong:
|
|
107
|
-
|
|
108
|
-
```ts
|
|
109
|
-
const pageIndex = table.atoms.pagination.get().pageIndex
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Correct:
|
|
113
|
-
|
|
114
|
-
```ts
|
|
115
|
-
const pageIndex = computed(() => table.atoms.pagination.get().pageIndex)
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
The first read is current but does not make its consumer reactive.
|
|
119
|
-
|
|
120
|
-
Source: `docs/framework/vue/guide/table-state.md`
|
|
121
|
-
|
|
122
|
-
### HIGH Passing state.value once
|
|
123
|
-
|
|
124
|
-
Wrong:
|
|
125
|
-
|
|
126
|
-
```ts
|
|
45
|
+
const state = computed(() => ({ pagination: pagination.value }))
|
|
127
46
|
const table = useTable({
|
|
128
47
|
features,
|
|
129
48
|
columns,
|
|
130
49
|
data,
|
|
131
|
-
state
|
|
50
|
+
state,
|
|
51
|
+
onPaginationChange: (next: Updater<PaginationState>) => {
|
|
52
|
+
pagination.value =
|
|
53
|
+
typeof next === 'function' ? next(pagination.value) : next
|
|
54
|
+
},
|
|
132
55
|
})
|
|
56
|
+
const pageSize = computed(() => table.atoms.pagination.get().pageSize)
|
|
133
57
|
```
|
|
134
58
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
```ts
|
|
138
|
-
const table = useTable({ features, columns, data, state: controlledState })
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
The adapter watches the computed ref; a one-time `.value` breaks future option synchronization.
|
|
142
|
-
|
|
143
|
-
Source: `packages/vue-table/src/useTable.ts`
|
|
144
|
-
|
|
145
|
-
### HIGH Assigning updater functions as values
|
|
146
|
-
|
|
147
|
-
Wrong:
|
|
148
|
-
|
|
149
|
-
```ts
|
|
150
|
-
const onPaginationChange = (next) => {
|
|
151
|
-
pagination.value = next
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
Correct:
|
|
156
|
-
|
|
157
|
-
```ts
|
|
158
|
-
const onPaginationChange = (next) => {
|
|
159
|
-
pagination.value = typeof next === 'function' ? next(pagination.value) : next
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
Table callbacks accept either a value or a function of the previous value.
|
|
164
|
-
|
|
165
|
-
Source: `examples/vue/basic-external-state/src/App.tsx`
|
|
166
|
-
|
|
167
|
-
### MEDIUM Supplying JSX children as a slot
|
|
168
|
-
|
|
169
|
-
Wrong:
|
|
170
|
-
|
|
171
|
-
```tsx
|
|
172
|
-
<table.Subscribe>
|
|
173
|
-
{(atoms) => <span>{atoms.pagination.get().pageIndex}</span>}
|
|
174
|
-
</table.Subscribe>
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
Correct:
|
|
178
|
-
|
|
179
|
-
```tsx
|
|
180
|
-
<table.Subscribe
|
|
181
|
-
children={(atoms) => <span>{atoms.pagination.get().pageIndex}</span>}
|
|
182
|
-
/>
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
The Vue adapter declares `Subscribe(props: { children })` and expects the explicit prop.
|
|
59
|
+
Assign the resolved updater result to the ref. For shared atom ownership, use a stable `@tanstack/vue-store` atom in `atoms.<slice>` instead of mirroring the same slice in controlled refs.
|
|
186
60
|
|
|
187
|
-
|
|
61
|
+
For computed-state synchronization failures, updater mistakes, or render boundaries, read [reactivity details](references/reactivity.md). If this task changes processing features, run `intent load @tanstack/table-core#table-features` and read the relevant feature references.
|
|
188
62
|
|
|
189
|
-
## API
|
|
63
|
+
## API discovery
|
|
190
64
|
|
|
191
|
-
Inspect `node_modules/@tanstack/vue-table/dist/useTable.d.ts` and `reactivity.d.ts`; inspect the
|
|
65
|
+
Inspect `node_modules/@tanstack/vue-table/dist/useTable.d.ts` and `reactivity.d.ts`; inspect the matching core feature declarations for the controlled slice.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Vue table reactive boundaries
|
|
2
|
+
|
|
3
|
+
Read when optimizing subscriptions, composing external atoms, or debugging Vue-specific tracking and controlled updates. Shared ownership, initialization, and reset rules remain in `intent load @tanstack/table-core#table-state`.
|
|
4
|
+
|
|
5
|
+
## Example context
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { computed, ref } from 'vue'
|
|
9
|
+
import {
|
|
10
|
+
rowPaginationFeature,
|
|
11
|
+
tableFeatures,
|
|
12
|
+
useTable,
|
|
13
|
+
} from '@tanstack/vue-table'
|
|
14
|
+
|
|
15
|
+
const features = tableFeatures({ rowPaginationFeature })
|
|
16
|
+
const data = ref([{ name: 'Ada' }])
|
|
17
|
+
const columns = [{ accessorKey: 'name' }]
|
|
18
|
+
const table = useTable({ features, columns, data })
|
|
19
|
+
const pageIndex = computed(() => table.atoms.pagination.get().pageIndex)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Internal state is usually enough. Atom reads are reactive only when Vue evaluates them in a tracked template, computed, watch, or render boundary.
|
|
23
|
+
|
|
24
|
+
## State patterns
|
|
25
|
+
|
|
26
|
+
### Control a slice without losing updater semantics
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { computed, ref } from 'vue'
|
|
30
|
+
import type { PaginationState } from '@tanstack/vue-table'
|
|
31
|
+
|
|
32
|
+
const pagination = ref<PaginationState>({ pageIndex: 0, pageSize: 20 })
|
|
33
|
+
const controlledState = computed(() => ({ pagination: pagination.value }))
|
|
34
|
+
const onPaginationChange = (
|
|
35
|
+
next: PaginationState | ((old: PaginationState) => PaginationState),
|
|
36
|
+
) => {
|
|
37
|
+
pagination.value = typeof next === 'function' ? next(pagination.value) : next
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Pass `state: controlledState` and `onPaginationChange` to `useTable`.
|
|
42
|
+
|
|
43
|
+
### Read atoms in a render function
|
|
44
|
+
|
|
45
|
+
Return JSX that reads the atom directly from the component's render function:
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
<span>{table.atoms.pagination.get().pageIndex + 1}</span>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`table.Subscribe` is deprecated and adds no subscription logic. Use a child component to isolate rendering when needed.
|
|
52
|
+
|
|
53
|
+
## Common mistakes
|
|
54
|
+
|
|
55
|
+
### HIGH Reading an untracked snapshot
|
|
56
|
+
|
|
57
|
+
Wrong:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
const pageIndex = table.atoms.pagination.get().pageIndex
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Correct:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
const pageIndex = computed(() => table.atoms.pagination.get().pageIndex)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The first read is current but does not make its consumer reactive.
|
|
70
|
+
|
|
71
|
+
Source: `docs/framework/vue/guide/table-state.md`
|
|
72
|
+
|
|
73
|
+
### HIGH Passing state.value once
|
|
74
|
+
|
|
75
|
+
Wrong:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
const table = useTable({
|
|
79
|
+
features,
|
|
80
|
+
columns,
|
|
81
|
+
data,
|
|
82
|
+
state: controlledState.value,
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Correct:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
const table = useTable({ features, columns, data, state: controlledState })
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The adapter watches the computed ref; a one-time `.value` breaks future option synchronization.
|
|
93
|
+
|
|
94
|
+
Source: `packages/vue-table/src/useTable.ts`
|
|
95
|
+
|
|
96
|
+
### HIGH Assigning updater functions as values
|
|
97
|
+
|
|
98
|
+
Wrong:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const onPaginationChange = (next) => {
|
|
102
|
+
pagination.value = next
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Correct:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
const onPaginationChange = (next) => {
|
|
110
|
+
pagination.value = typeof next === 'function' ? next(pagination.value) : next
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Table callbacks accept either a value or a function of the previous value.
|
|
115
|
+
|
|
116
|
+
Source: `examples/vue/basic-external-state/src/App.tsx`
|
|
117
|
+
|
|
118
|
+
## API discovery
|
|
119
|
+
|
|
120
|
+
Inspect `node_modules/@tanstack/vue-table/dist/useTable.d.ts` and `reactivity.d.ts`; inspect the exact state slice in the installed core feature directory.
|
|
121
|
+
|
|
122
|
+
## Sources
|
|
123
|
+
|
|
124
|
+
- `TanStack/table:docs/framework/vue/guide/table-state.md`
|
|
125
|
+
- `TanStack/table:examples/vue/basic-external-state`
|
|
126
|
+
- `TanStack/table:packages/vue-table/src/useTable.ts`
|