Skip to main content

Usage

The Table component provides a full-featured data table implementation using @tanstack/vue-table. It supports sorting, filtering, pagination, row selection, column pinning, virtualization, and more.
<script setup>
const data = [
  { id: 1, name: 'John Doe', email: '[email protected]', role: 'Admin' },
  { id: 2, name: 'Jane Smith', email: '[email protected]', role: 'User' },
  { id: 3, name: 'Bob Johnson', email: '[email protected]', role: 'User' }
]

const columns = [
  { accessorKey: 'name', header: 'Name' },
  { accessorKey: 'email', header: 'Email' },
  { accessorKey: 'role', header: 'Role' }
]
</script>

<template>
  <UTable :data="data" :columns="columns" />
</template>

Props

data
T[]
The data array to display in the table.
columns
TableColumn<T>[]
Array of column definitions. Each column can have accessorKey, header, cell, footer, and more TanStack Table column options.
as
any
default:"'div'"
The element or component this component should render as.
caption
string
Optional caption text for the table.
meta
TableMeta<T>
Table metadata including custom class and style functions for rows.
virtualize
boolean | VirtualizerOptions
default:"false"
Enable virtualization for large datasets. When enabled, only visible rows are rendered. Note: divider and sticky properties are not supported with virtualization.You can pass true for default settings or an object with:
  • overscan (number): Number of items rendered outside the visible area. Default: 12
  • estimateSize (number | function): Estimated size in px of each item. Default: 65
empty
string
default:"t('table.noData')"
The text to display when the table is empty.
sticky
boolean | 'header' | 'footer'
default:"false"
Whether the table should have a sticky header or footer. Use true for both, 'header' for header only, or 'footer' for footer only. Not supported when virtualize is true.
loading
boolean
Whether the table should be in loading state.
loadingColor
string
default:"'primary'"
Color of the loading indicator.
loadingAnimation
string
default:"'carousel'"
Animation style for the loading indicator.
watchOptions
WatchOptions
default:"{ deep: true }"
Customize reactivity for data changes. Disable deep watching or limit traversal depth to improve performance.

TanStack Table Feature Props

The Table component supports all TanStack Table features through dedicated props:
globalFilterOptions
GlobalFilterOptions<T>
Options for global filtering. See TanStack Table Global Filtering Guide.
columnFiltersOptions
ColumnFiltersOptions<T>
Options for column filtering. See TanStack Table Column Filtering Guide.
columnPinningOptions
ColumnPinningOptions
Options for column pinning. See TanStack Table Column Pinning Guide.
columnSizingOptions
ColumnSizingOptions
Options for column sizing. See TanStack Table Column Sizing Guide.
visibilityOptions
VisibilityOptions
Options for column visibility. See TanStack Table Column Visibility Guide.
sortingOptions
SortingOptions<T>
Options for sorting. See TanStack Table Sorting Guide.
groupingOptions
GroupingOptions
Options for grouping. See TanStack Table Grouping Guide.
expandedOptions
ExpandedOptions<T>
Options for row expanding. See TanStack Table Expanding Guide.
rowSelectionOptions
RowSelectionOptions<T>
Options for row selection. See TanStack Table Row Selection Guide.
rowPinningOptions
RowPinningOptions<T>
Options for row pinning. See TanStack Table Row Pinning Guide.
paginationOptions
PaginationOptions
Options for pagination. See TanStack Table Pagination Guide.
facetedOptions
FacetedOptions<T>
Options for column faceting. See TanStack Table Column Faceting Guide.

Event Handlers

onSelect
(e: Event, row: TableRow<T>) => void
Callback fired when a row is selected/clicked.
onHover
(e: Event, row: TableRow<T> | null) => void
Callback fired when a row is hovered.
onContextmenu
((e: Event, row: TableRow<T>) => void) | Array<(e: Event, row: TableRow<T>) => void>
Callback(s) fired when a row is right-clicked.
class
any
Additional CSS classes to apply.
ui
object
UI customization object for styling table slots.

Models (v-model)

The Table component provides v-model bindings for all TanStack Table state:
v-model:globalFilter
string
Global filter value.
v-model:columnFilters
ColumnFiltersState
Column filter state.
v-model:columnOrder
ColumnOrderState
Column order state.
v-model:columnVisibility
VisibilityState
Column visibility state.
v-model:columnPinning
ColumnPinningState
Column pinning state.
v-model:columnSizing
ColumnSizingState
Column sizing state.
v-model:columnSizingInfo
ColumnSizingInfoState
Column sizing info state.
v-model:rowSelection
RowSelectionState
Row selection state.
v-model:rowPinning
RowPinningState
Row pinning state.
v-model:sorting
SortingState
Sorting state.
v-model:grouping
GroupingState
Grouping state.
v-model:expanded
ExpandedState
Expanded rows state.
v-model:pagination
PaginationState
Pagination state.

Slots

expanded
{ row: Row<T> }
Content to display when a row is expanded.
empty
{}
Custom content to display when the table is empty.
loading
{}
Custom content to display when the table is loading.
caption
{}
Custom table caption content.
body-top
{}
Content to insert at the top of the table body.
body-bottom
{}
Content to insert at the bottom of the table body.
{columnId}-header
HeaderContext<T, unknown>
Custom header content for a specific column. Replace {columnId} with the column’s ID.
Custom footer content for a specific column. Replace {columnId} with the column’s ID.
{columnId}-cell
CellContext<T, unknown>
Custom cell content for a specific column. Replace {columnId} with the column’s ID.

Examples

Sortable Columns

<script setup>
const sorting = ref([])

const columns = [
  {
    accessorKey: 'name',
    header: 'Name',
    enableSorting: true
  },
  {
    accessorKey: 'email',
    header: 'Email',
    enableSorting: true
  }
]
</script>

<template>
  <UTable 
    :data="data" 
    :columns="columns" 
    v-model:sorting="sorting"
    :sorting-options="{ enableSorting: true }"
  />
</template>

Row Selection

<script setup>
const rowSelection = ref({})

const columns = [
  {
    id: 'select',
    header: ({ table }) => (
      h(UCheckbox, {
        checked: table.getIsAllRowsSelected(),
        indeterminate: table.getIsSomeRowsSelected(),
        onUpdate:modelValue: (value) => table.toggleAllRowsSelected(!!value)
      })
    ),
    cell: ({ row }) => (
      h(UCheckbox, {
        checked: row.getIsSelected(),
        onUpdate:modelValue: (value) => row.toggleSelected(!!value)
      })
    )
  },
  // ... other columns
]
</script>

<template>
  <UTable 
    :data="data" 
    :columns="columns" 
    v-model:rowSelection="rowSelection"
    :row-selection-options="{ enableRowSelection: true }"
  />
</template>

Pagination

<script setup>
const pagination = ref({ pageIndex: 0, pageSize: 10 })
</script>

<template>
  <UTable 
    :data="data" 
    :columns="columns" 
    v-model:pagination="pagination"
    :pagination-options="{ 
      pageCount: Math.ceil(data.length / pagination.pageSize)
    }"
  />
</template>

Custom Cell Rendering

<script setup>
const columns = [
  {
    accessorKey: 'name',
    header: 'Name',
    cell: ({ getValue }) => h('strong', getValue())
  },
  {
    accessorKey: 'status',
    header: 'Status',
    cell: ({ getValue }) => {
      const status = getValue()
      return h(UBadge, {
        color: status === 'active' ? 'green' : 'gray',
        label: status
      })
    }
  }
]
</script>

<template>
  <UTable :data="data" :columns="columns" />
</template>

Virtualization for Large Datasets

<template>
  <UTable 
    :data="largeDataset" 
    :columns="columns" 
    :virtualize="{
      overscan: 20,
      estimateSize: 50
    }"
  />
</template>

Column Metadata

Use column metadata to customize styling:
<script setup>
const columns = [
  {
    accessorKey: 'name',
    header: 'Name',
    meta: {
      class: {
        th: 'font-bold',
        td: (cell) => cell.getValue() === 'Admin' ? 'text-primary' : ''
      },
      style: {
        th: { width: '200px' },
        td: { fontWeight: '500' }
      }
    }
  }
]
</script>

Type Exports

import type { 
  TableRow,
  TableData,
  TableColumn,
  TableOptions,
  TableProps,
  TableSlots
} from '#ui/types'

API Reference

For detailed information about column definitions, features, and options, refer to the TanStack Table documentation.

Build docs developers (and LLMs) love