@tanstack/vue-table
Version:
Headless UI for building powerful tables & datagrids for Vue.
145 lines (108 loc) • 3.81 kB
Markdown
---
name: getting-started
description: >
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.
metadata:
type: framework
library: '@tanstack/vue-table'
framework: vue
library_version: '9.0.0'
requires:
- '@tanstack/table-core#core'
- '@tanstack/table-core#table-features'
sources:
- 'TanStack/table:docs/framework/vue/guide/migrating.md'
- 'TanStack/table:examples/vue/basic-use-table'
- 'TanStack/table:packages/vue-table/src/index.ts'
---
This skill builds on `@tanstack/table-core#core` and `@tanstack/table-core#table-features`. Read them first for the headless model and explicit feature registration.
## Setup
```vue
<script setup lang="ts">
import { ref } from 'vue'
import { FlexRender, tableFeatures, useTable } from '@tanstack/vue-table'
type Person = { name: string; age: number }
const features = tableFeatures({})
const columns = [
{ accessorKey: 'name', header: 'Name' },
{ accessorKey: 'age', header: 'Age' },
]
const data = ref<Person[]>([{ name: 'Ada', age: 36 }])
const table = useTable({ features, columns, data })
</script>
<template>
<table>
<thead>
<tr v-for="group in table.getHeaderGroups()" :key="group.id">
<th v-for="header in group.headers" :key="header.id">
<FlexRender v-if="!header.isPlaceholder" :header="header" />
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in table.getRowModel().rows" :key="row.id">
<td v-for="cell in row.getAllCells()" :key="cell.id">
<FlexRender :cell="cell" />
</td>
</tr>
</tbody>
</table>
</template>
```
## Core Patterns
### Preserve Vue option shapes
`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.
### Add a client row model explicitly
```ts
import {
createSortedRowModel,
rowSortingFeature,
sortFn_alphanumeric,
tableFeatures,
} from '@tanstack/vue-table'
const features = tableFeatures({
rowSortingFeature,
sortedRowModel: createSortedRowModel(),
sortFns: { alphanumeric: sortFn_alphanumeric },
})
```
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.
## Common Mistakes
### HIGH Flattening a ref into a snapshot
Wrong:
```ts
const table = useTable({ features, columns, data: data.value })
```
Correct:
```ts
const table = useTable({ features, columns, data })
```
Passing `.value` captures one array instead of letting the adapter watch the ref.
Source: `packages/vue-table/src/useTable.ts`
### HIGH Using the v8 entrypoint
Wrong:
```ts
const table = useVueTable({ data, columns, getCoreRowModel: getCoreRowModel() })
```
Correct:
```ts
const table = useTable({ features, columns, data })
```
V9 uses `useTable`; core processing is automatic and optional row models live in `tableFeatures`.
Source: `docs/framework/vue/guide/migrating.md`
### HIGH Assuming headless means prebuilt UI
Wrong:
```vue
<TanStackTable :table="table" />
```
Correct:
```vue
<td
v-for="cell in row.getAllCells()"
:key="cell.id"
><FlexRender :cell="cell" /></td>
```
The adapter renders definitions but owns no table component, CSS, or design-system integration.
Source: `examples/vue/basic-use-table/src/App.tsx`
## API Discovery
Inspect `node_modules/@tanstack/vue-table/dist/index.d.ts`, then `useTable.d.ts` and `FlexRender.d.ts`. Inspect core feature APIs in `node_modules/@tanstack/table-core/dist/features/<feature>/`.