Skip to content

DataTable ​

A Neo-Brutalist data table component providing comprehensive sorting, filtering, multi-selection, pagination, and virtual scrolling functionality. Supports generic data sources with flexible data presentation through columns-driven column configuration.

Demo ​

Preview
姓名
邮箱
角色
状态
张三zhangsan@example.com管理员活跃
李四lisi@example.com编辑活跃
王五wangwu@example.com查看者未活跃
赵六zhaoliu@example.com编辑活跃
孙七sunqi@example.com管理员未活跃

Installation ​

pnpm dlx brutx-vue@latest add data-table

Usage ​

Basic Usage ​

vue
<script setup lang="ts">
import { ref } from 'vue'
import { DataTable } from 'brutx-ui-vue'
import type { DataTableColumn } from 'brutx-ui-vue'

interface User {
    id: number
    name: string
    email: string
    role: string
    status: string
}

const columns: DataTableColumn<User>[] = [
    {
        id: 'name',
        header: 'Name',
        accessorKey: 'name',
        sortable: true,
    },
    {
        id: 'email',
        header: 'Email',
        accessorKey: 'email',
        sortable: true,
    },
    {
        id: 'role',
        header: 'Role',
        accessorKey: 'role',
    },
    {
        id: 'status',
        header: 'Status',
        accessorKey: 'status',
        align: 'center',
    },
]

const data = ref<User[]>([
    { id: 1, name: 'John', email: 'john@example.com', role: 'Admin', status: 'Active' },
    { id: 2, name: 'Jane', email: 'jane@example.com', role: 'Editor', status: 'Active' },
    { id: 3, name: 'Bob', email: 'bob@example.com', role: 'Guest', status: 'Inactive' },
])
</script>

<template>
    <DataTable
        :data="data"
        :columns="columns"
        :sortable="true"
        row-key="id"
    />
</template>

Enabling Sorting ​

vue
<template>
    <DataTable
        :data="data"
        :columns="columns"
        :sortable="true"
        row-key="id"
        @sort="handleSort"
    />
</template>

Enable sorting via the sortable prop. Set sortable: false in column definitions to disable sorting for specific columns. Clicking the header toggles between ascending / descending / default.

Enabling Filtering ​

vue
<template>
    <DataTable
        :data="data"
        :columns="columns"
        :filterable="true"
        row-key="id"
        @filter="handleFilter"
    />
</template>

Enabling filterable displays a global search input above the table, performing fuzzy matching across all visible columns.

Enabling Selection ​

vue
<template>
    <DataTable
        :data="data"
        :columns="columns"
        :selectable="true"
        row-key="id"
        @select="handleSelect"
    />
</template>

Enabling selectable displays checkboxes on the left side of each row. The header checkbox supports select all / deselect all. When rows are selected, the bottom displays the count of selected rows with CSV export capability.

Enabling Pagination ​

vue
<template>
    <DataTable
        :data="data"
        :columns="columns"
        :paginated="true"
        :page-size="10"
        :page-size-options="[10, 20, 50]"
        row-key="id"
        @page-change="handlePageChange"
        @page-size-change="handlePageSizeChange"
    />
</template>

The paginator includes first page, previous page, next page, last page buttons, and a page size selector.

Column Filters ​

Supports adding a Popover filter in the header of each column. Supports text search, single selection (Select), multi-selection (Multi-Select), and date range (Date Range) filtering.

date-range filters parse YYYY-MM-DD cell strings as local calendar dates and include the end date through 23:59:59.999 for that local day. Full datetime strings still use native Date / ISO datetime semantics; if your data must compare consistently across time zones, store values as Date, timestamps, or full ISO strings with explicit offsets.

vue
<script setup lang="ts">
const columns = [
    { id: 'name', header: 'Name', accessorKey: 'name', filterType: 'text' },
    {
        id: 'role',
        header: 'Role',
        accessorKey: 'role',
        filterType: 'select',
        filterOptions: [
            { label: 'Admin', value: 'Admin' },
            { label: 'Editor', value: 'Editor' }
        ]
    },
    {
        id: 'status',
        header: 'Status',
        accessorKey: 'status',
        filterType: 'multi-select',
        filterOptions: [
            { label: 'Active', value: 'Active' },
            { label: 'Inactive', value: 'Inactive' }
        ]
    },
    {
        id: 'date',
        header: 'Hire Date',
        accessorKey: 'date',
        filterType: 'date-range'
    }
]
</script>

<template>
    <DataTable
        :data="data"
        :columns="columns"
        :filterable="true"
        row-key="id"
    />
</template>

Custom Cell Rendering ​

vue
<script setup lang="ts">
import { h } from 'vue'
import { Badge } from 'brutx-ui-vue'
import type { DataTableColumn } from 'brutx-ui-vue'

const columns: DataTableColumn<User>[] = [
    { id: 'name', header: 'Name', accessorKey: 'name' },
    {
        id: 'status',
        header: 'Status',
        accessorKey: 'status',
        cell: ({ value }) => {
            return h(Badge, { variant: value === 'Active' ? 'success' : 'danger' }, () => String(value))
        },
    },
]
</script>

The cell function enables custom cell rendering, supporting VNode or string return values. You can also use named slots #cell-{columnId} for rendering.

Using Slots ​

vue
<template>
    <DataTable
        :data="data"
        :columns="columns"
        row-key="id"
    >
        <template #cell-status="{ row, value }">
            <Badge :variant="value === 'Active' ? 'success' : 'danger'">
                {{ value }}
            </Badge>
        </template>

        <template #toolbar>
            <Button variant="primary" size="sm">
                Add User
            </Button>
        </template>

        <template #empty>
            <div class="text-center py-8">
                <p class="text-lg font-bold">No Data</p>
                <p class="text-sm text-brutal-fg/60">Click the button above to add your first record</p>
            </div>
        </template>
    </DataTable>
</template>

Loading State ​

vue
<template>
    <DataTable
        :data="data"
        :columns="columns"
        :loading="isLoading"
        row-key="id"
    />
</template>

When loading is true, a spinning loader overlay appears above the table. You can also customize loading content via the loading named slot.

Sizes ​

vue
<template>
    <!-- Small size + compact density, ideal for information-dense tables -->
    <DataTable
        :data="data"
        :columns="columns"
        :sortable="true"
        size="sm"
        :dense="true"
        row-key="id"
    />

    <!-- Large size, ideal for display-oriented tables -->
    <DataTable
        :data="data"
        :columns="columns"
        size="lg"
        row-key="id"
    />
</template>

size controls font size and vertical cell padding (sm -> py-2, default -> py-3, lg -> py-4); dense further compresses row height to py-1.5, orthogonal to size, and can be used independently or in combination.

Stripe Control ​

vue
<template>
    <!-- Stripes enabled by default (even rows bg-brutal-muted/50) -->
    <DataTable
        :data="data"
        :columns="columns"
        row-key="id"
    />

    <!-- Explicitly disable stripes -->
    <DataTable
        :data="data"
        :columns="columns"
        :striped="false"
        row-key="id"
    />
</template>

striped defaults to true, applying bg-brutal-muted/50 to even rows for alternating row colors. Set to false for a clean appearance or when using custom row backgrounds.

vue
<template>
    <DataTable
        :data="largeData"
        :columns="columns"
        :sticky-header="true"
        row-key="id"
    />
</template>

When stickyHeader is enabled, the header stays at the top of the visible area while the page or an outer vertical scroll container moves. The header follows the body during horizontal scrolling; virtual rows keep their own vertical scroll area.

Data Types ​

DataTableColumn ​

FieldTypeDescription
idstringColumn unique identifier, required
headerstring | ((ctx: DataTableColumnHeaderContext) => string)Column header, required; function form receives DataTableColumnHeaderContext context
accessorKeykeyof T & stringAccess row data field by key
accessorFn(row: T) => unknownAccess row data value by function
cell(props: { row: T; value: unknown }) => VNode | stringCustom cell rendering
sortablebooleanWhether sortable, defaults to true
hiddenbooleanWhether hidden
widthnumber | 'auto'Column width
minWidthnumberMinimum width
maxWidthnumberMaximum width
align'left' | 'center' | 'right'Alignment
filterType'text' | 'select' | 'multi-select' | 'date-range'Filter type, displays corresponding filter popover in column header
filterOptionsArray<{ label: string; value: any }>Filter options, used for select and multi-select filters

DataTableColumnHeaderContext ​

Context object received by the header callback function, used to access the column's runtime state in functional headers.

FieldTypeDescription
idstringCurrent column ID
sortablebooleanWhether the current column is sortable
direction'asc' | 'desc' | nullCurrent column sort direction (null means unsorted)
accessorKeyPropertyKeyCurrent column's accessorKey (if any)
align'left' | 'center' | 'right'Current column's alignment

DataTableVirtualScroll ​

FieldTypeDefaultDescription
enabledboolean—Whether to enable virtual scrolling
rowHeightnumber | 'auto'48Estimated row height (pixels), 'auto' to observe and measure dynamic height via DOM (requires all columns to have explicit width configuration)

DataTableFilterState ​

FieldTypeDescription
globalstringGlobal filter keyword
columnsRecord<string, any>Column-level filter values indexed by column ID

Programmatic Control ​

DataTable exposes sorting, filtering, selection, and pagination methods and state via defineExpose. These can be called directly from the parent component through a component ref, enabling scenarios like "external toolbars", "external sort triggers", and "batch operation buttons".

vue
<script setup lang="ts">
import { ref } from 'vue'
import { DataTable, Button } from 'brutx-ui-vue'
import type { DataTableColumn } from 'brutx-ui-vue'

interface User {
    id: number
    name: string
    email: string
    role: string
    status: string
}

const tableRef = ref<InstanceType<typeof DataTable> | null>(null)

const columns: DataTableColumn<User>[] = [
    { id: 'name', header: 'Name', accessorKey: 'name', sortable: true },
    { id: 'email', header: 'Email', accessorKey: 'email' },
    { id: 'role', header: 'Role', accessorKey: 'role' },
    { id: 'status', header: 'Status', accessorKey: 'status' },
]

const data: User[] = [
    { id: 1, name: 'John', email: 'john@example.com', role: 'Admin', status: 'Active' },
    { id: 2, name: 'Jane', email: 'jane@example.com', role: 'Editor', status: 'Inactive' },
    { id: 3, name: 'Bob', email: 'bob@example.com', role: 'Guest', status: 'Active' },
]

// Programmatically sort by name ascending
function sortByNameAsc() {
    tableRef.value?.sort.toggleSort('name')
}

// Programmatically set global filter keyword
function filterByAdmin() {
    tableRef.value?.filter.setGlobalFilter('Admin')
}

// Select all on current page
function selectAll() {
    tableRef.value?.selection.toggleAllRows()
}

// Go to next page
function goNextPage() {
    tableRef.value?.pagination.nextPage()
}
</script>

<template>
    <div class="flex flex-wrap items-center gap-2 mb-4">
        <Button variant="primary" size="sm" @click="sortByNameAsc">Sort by Name</Button>
        <Button variant="default" size="sm" @click="filterByAdmin">Filter "Admin"</Button>
        <Button variant="default" size="sm" @click="selectAll">Select All on Page</Button>
        <Button variant="default" size="sm" @click="goNextPage">Next Page</Button>
    </div>

    <DataTable
        ref="tableRef"
        :data="data"
        :columns="columns"
        :sortable="true"
        :filterable="true"
        :selectable="true"
        :paginated="true"
        :page-size="2"
        row-key="id"
    />
</template>

Exposed Members ​

A component ref provides sorting, filtering, selection, pagination, and row-expansion namespaces and their state. See the API reference below for every exposed member. Programmatic sort.toggleSort and selection state mutations do not emit sort or select; filter state changes still emit filter; pagination methods do not emit page-change or page-size-change; expand.toggleRow emits expand-change.

API Reference ​

DataTable

DataTable — Props
NameTypeDefaultDescription
class
string | undefined
—
Custom CSS classes added to the table root container.
Details

Declared type

string | undefined

Default value details

Not declared
—

Source

data-table.ts:86

packages/ui/src/types/data-table.ts

data
Required
T[]
—
The rows to display. Generic type T is carried through column definitions, row events, and the programmatic API.
Details

Declared type

T[]

Default value details

Not declared
—

Source

data-table.ts:55

packages/ui/src/types/data-table.ts

columns
Required
DataTableColumn<T>[]
—
The column definitions that control headers, value access, sorting, filtering, rendering, and column layout.
Details

Declared type

DataTableColumn<T>[]

Referenced types

DataTableColumn
Type definition — DataTableColumn
export interface DataTableColumn<T extends object = Record<string, unknown>> {
    id: string
    /** 函数签名已更新:回调参数从 DataTableColumn<T> 改为 DataTableColumnHeaderContext */
    header: string | ((ctx: DataTableColumnHeaderContext) => string)
    accessorKey?: keyof T & string
    accessorFn?: (row: T) => unknown
    cell?: (props: { row: T; value: unknown }) => VNode | string
    sortable?: boolean
    hidden?: boolean
    width?: number | 'auto'
    minWidth?: number
    maxWidth?: number
    align?: 'left' | 'center' | 'right'
    /** 固定列方向 */
    fixed?: 'left' | 'right'
    /** 列类型 */
    type?: 'default' | 'expand'
    /** 过滤器类型 */
    filterType?: 'text' | 'select' | 'multi-select' | 'date-range'
    /** 过滤可选项 */
    filterOptions?: Array<{ label: string; value: string | number }>
}

Default value details

Not declared
—

Source

data-table.ts:56

packages/ui/src/types/data-table.ts

sortable
boolean | undefined
false
Enables sortable-column header interaction and sorted data; an individual column can opt out with sortable: false.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

data-table.ts:57

packages/ui/src/types/data-table.ts

filterable
boolean | undefined
false
Shows the global search input and column filters for columns that declare filterType.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

data-table.ts:58

packages/ui/src/types/data-table.ts

filterPlaceholder
string | undefined
undefined
The global search input placeholder and accessible name; when omitted, the localized dataTable.filterPlaceholder message is used.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

data-table.ts:59

packages/ui/src/types/data-table.ts

selectable
boolean | undefined
false
Shows row checkboxes and a select-all checkbox, and enables reading and exporting selected rows.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

data-table.ts:60

packages/ui/src/types/data-table.ts

paginated
boolean | undefined
false
Enables page slicing and the pagination controls.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

data-table.ts:61

packages/ui/src/types/data-table.ts

pageSize
number | undefined
10
The number of rows per page when pagination is enabled; data is not sliced into pages when pagination is disabled.
Details

Declared type

number | undefined

Default value details

Declaration
DEFAULT_PAGE_SIZE

Source: packages/ui/src/components/data-table/DataTable.vue

Resolved value
10

Source

data-table.ts:62

packages/ui/src/types/data-table.ts

pageSizeOptions
number[] | undefined
[10, 20, 50, 100]

Factory evaluated per instance

The page sizes offered by the pagination control.
Details

Declared type

number[] | undefined

Default value details

Declaration
() => [...DEFAULT_PAGE_SIZE_OPTIONS]

Source: packages/ui/src/components/data-table/DataTable.vue

Resolved value
[10, 20, 50, 100]

Source

data-table.ts:63

packages/ui/src/types/data-table.ts

loading
boolean | undefined
false
Displays the loading overlay and the loading slot content.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

data-table.ts:64

packages/ui/src/types/data-table.ts

emptyMessage
string | undefined
—
The empty-state message; when omitted or empty, the localized dataTable.noData message is used.
Details

Declared type

string | undefined

Default value details

Not declared
—

Source

data-table.ts:65

packages/ui/src/types/data-table.ts

rowKey
Required
keyof T | ((row: T) => string | number)
—
Provides a unique row-key field or accessor; row selection and expansion rely on the resolved string or number key.
Details

Declared type

keyof T | ((row: T) => string | number)

Default value details

Not declared
—

Source

data-table.ts:66

packages/ui/src/types/data-table.ts

rowClickable
boolean | undefined
false
Makes a row activate the row-click event through pointer click or the Enter key.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

data-table.ts:67

packages/ui/src/types/data-table.ts

title
string | undefined
undefined
The heading shown above the table when the header slot is not supplied.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

data-table.ts:68

packages/ui/src/types/data-table.ts

description
string | undefined
undefined
The supporting text shown below the heading when the header slot is not supplied.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

data-table.ts:69

packages/ui/src/types/data-table.ts

section
boolean | undefined
false
Applies a constrained width and centered layout to the table root container.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

data-table.ts:70

packages/ui/src/types/data-table.ts

framed
boolean | undefined
true
Controls the root border, shadow, and rounded corners; false removes those frame styles.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
true

Source

data-table.ts:71

packages/ui/src/types/data-table.ts

virtualScroll
DataTableVirtualScroll | undefined
—
Configures row virtualization. It is enabled when enabled is true; rowHeight can be fixed or measured dynamically with auto.
Details

Declared type

DataTableVirtualScroll | undefined

Referenced types

DataTableVirtualScroll
Type definition — DataTableVirtualScroll
export interface DataTableVirtualScroll {
    enabled?: boolean
    rowHeight?: number | 'auto'
}

Default value details

Not declared
—

Source

data-table.ts:72

packages/ui/src/types/data-table.ts

size
"default" | "lg" | "sm" | undefined
"default"
Sets the table size variant.
Details

Declared type

"default" | "lg" | "sm" | undefined

Literal values

  • "default"
  • "lg"
  • "sm"

Default value details

Resolved value
"default"

Source

data-table.ts:73

packages/ui/src/types/data-table.ts

dense
boolean | undefined
false
Uses more compact row and cell spacing.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

data-table.ts:74

packages/ui/src/types/data-table.ts

striped
boolean | undefined
true
Controls alternating background stripes on data rows.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
true

Source

data-table.ts:75

packages/ui/src/types/data-table.ts

stickyHeader
boolean | undefined
false
Keeps the header at the top of the visible area during page or outer-container vertical scrolling and synchronizes it with horizontal body scrolling.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

data-table.ts:76

packages/ui/src/types/data-table.ts

expandable
boolean | undefined
false
Shows row expansion controls and allows the expanded-row slot to render.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

data-table.ts:78

packages/ui/src/types/data-table.ts

expandRowKeys
Set<string | number> | undefined
undefined
The controlled set of expanded row keys. Keys must match rowKey resolution, and changes synchronize the internal expansion state.
Details

Declared type

Set<string | number> | undefined

Default value details

Resolved value
undefined

Source

data-table.ts:83

packages/ui/src/types/data-table.ts

spanMethod
((params: DataTableSpanMethodParams<T>) => void | [number, number]) | undefined
undefined
Calculates a merge span for each displayed row and visible column. Return rowspan and colspan, or nothing to use the default span.
Details

Declared type

((params: DataTableSpanMethodParams<T>) => void | [number, number]) | undefined

Default value details

Resolved value
undefined

Source

data-table.ts:85

packages/ui/src/types/data-table.ts

DataTable — Events
NameSignature or typeDescription
@sort
[column: string, direction: "asc" | "desc" | null]
Emits the column ID and direction after the user interacts with a sortable header; direction is asc, desc, or null.
Details

Declared type

[column: string, direction: "asc" | "desc" | null]

Literal values

  • "asc"
  • "desc"
  • null

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

@filter
[filters: DataTableFilterState]
Emits the current global and column filter state when filtering changes.
Details

Declared type

[filters: DataTableFilterState]

Referenced types

DataTableFilterState
Type definition — DataTableFilterState
export interface DataTableFilterState {
    global?: string
    columns: Record<string, DataTableFilterValue>
}

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

@select
[rows: T[]]
Emits the selected row data array after the user toggles a row or the current-page select-all control.
Details

Declared type

[rows: T[]]

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

@page-change
[page: number]
Emits the page number after user navigation changes the current page; no event is emitted when the page stays the same.
Details

Declared type

[page: number]

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

@page-size-change
[size: number]
Emits the new page size after the user selects it in the pagination control.
Details

Declared type

[size: number]

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

@expand-change
[row: T, expanded: boolean]
Emits the row data and its new expanded boolean when the row expansion state toggles.
Details

Declared type

[row: T, expanded: boolean]

Literal values

  • false
  • true

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

@row-click
[row: T]
When rowClickable is enabled, emits row data after a pointer click or Enter activation; events originating inside buttons, inputs, links, or other interactive elements are ignored.
Details

Declared type

[row: T]

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

@export
[format: "csv" | "json", selectedRows?: T[] | undefined]
Emits the selected format and current selected-row array when a table export control is activated.
Details

Declared type

[format: "csv" | "json", selectedRows?: T[] | undefined]

Literal values

  • "csv"
  • "json"

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

DataTable — Slots
NameSignature or typeDescription
#header
{}
Replaces the default table header; when omitted, the heading area is rendered from title and description.
Details

Declared type

{}

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

#toolbar
{}
Additional content for the global filtering toolbar; when filterable is enabled, it appears beside the search input.
Details

Declared type

{}

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

#expanded-row
{ row: T; index: number; }
Additional expanded-row content with row and its index in the displayed list; rendered only for an expanded row when expandable is enabled.
Details

Declared type

{ row: T; index: number; }

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

#empty
{}
Replaces the empty-state content; rendered only when there is no display data and loading is false.
Details

Declared type

{}

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

#loading
{}
Replaces the loading overlay content; rendered only when loading is true.
Details

Declared type

{}

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

#cell-{columnId}
{ row: T; value: unknown }
Provides custom content for a column cell. Use the cell-{columnId} slot name; its scope exposes the current row and cell value.
  • Used only for regular data columns. If absent, the table falls back to the column cell renderer or the default cell value.
Details

Declared type

{ row: T; value: unknown }

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

DataTable — Exposes
NameSignature or typeDescription
sort
{ toggleSort: (columnId: string) => void; sortState: Readonly<Ref<{ readonly column: string; readonly direction: "asc" | "desc" | null; }, { readonly column: string; readonly direction: "asc" | "desc" | null; }>>; }
The table sorting namespace, containing toggleSort and the read-only sortState.
Details

Declared type

{ toggleSort: (columnId: string) => void; sortState: Readonly<Ref<{ readonly column: string; readonly direction: "asc" | "desc" | null; }, { readonly column: string; readonly direction: "asc" | "desc" | null; }>>; }

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

sort.toggleSort
(columnId: string) => void
Toggles sorting for a column ID. Sorting must be enabled and the column must not opt out; the cycle is ascending, descending, then cleared.
Details

Declared type

(columnId: string) => void

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

sort.sortState
Readonly
Readonly<Ref<{ readonly column: string; readonly direction: "asc" | "desc" | null; }, { readonly column: string; readonly direction: "asc" | "desc" | null; }>>
The read-only reactive sort state containing the current column ID and asc, desc, or null direction.
Details

Declared type

Readonly<Ref<{ readonly column: string; readonly direction: "asc" | "desc" | null; }, { readonly column: string; readonly direction: "asc" | "desc" | null; }>>

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

filter
{ filterState: Readonly<Ref<{ readonly global?: string | undefined; readonly columns: { readonly [x: string]: string | number | readonly (string | number)[] | { readonly start: string | null; readonly end: string | null; } | null | undefined; }; }, { readonly global?: string | undefined; readonly columns: { readonly [x: string]: string | number | readonly (string | number)[] | { readonly start: string | null; readonly end: string | null; } | null | undefined; }; }>>; setGlobalFilter: (value: string) => void; setFilterState: (state: DataTableFilterState) => void; }
The table filtering namespace, providing state access and methods to set global or complete filter criteria.
Details

Declared type

{ filterState: Readonly<Ref<{ readonly global?: string | undefined; readonly columns: { readonly [x: string]: string | number | readonly (string | number)[] | { readonly start: string | null; readonly end: string | null; } | null | undefined; }; }, { readonly global?: string | undefined; readonly columns: { readonly [x: string]: string | number | readonly (string | number)[] | { readonly start: string | null; readonly end: string | null; } | null | undefined; }; }>>; setGlobalFilter: (value: string) => void; setFilterState: (state: DataTableFilterState) => void; }

Referenced types

DataTableFilterState
Type definition — DataTableFilterState
export interface DataTableFilterState {
    global?: string
    columns: Record<string, DataTableFilterValue>
}

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

filter.filterState
Readonly
Readonly<Ref<{ readonly global?: string | undefined; readonly columns: { readonly [x: string]: string | number | readonly (string | number)[] | { readonly start: string | null; readonly end: string | null; } | null | undefined; }; }, { readonly global?: string | undefined; readonly columns: { readonly [x: string]: string | number | readonly (string | number)[] | { readonly start: string | null; readonly end: string | null; } | null | undefined; }; }>>
The read-only reactive filter state, with an optional global value and columns indexed by column ID.
Details

Declared type

Readonly<Ref<{ readonly global?: string | undefined; readonly columns: { readonly [x: string]: string | number | readonly (string | number)[] | { readonly start: string | null; readonly end: string | null; } | null | undefined; }; }, { readonly global?: string | undefined; readonly columns: { readonly [x: string]: string | number | readonly (string | number)[] | { readonly start: string | null; readonly end: string | null; } | null | undefined; }; }>>

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

filter.setGlobalFilter
(value: string) => void
Sets the global search keyword.
Details

Declared type

(value: string) => void

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

filter.setFilterState
(state: DataTableFilterState) => void
Replaces the complete filtering state with the supplied DataTableFilterState.
Details

Declared type

(state: DataTableFilterState) => void

Referenced types

DataTableFilterState
Type definition — DataTableFilterState
export interface DataTableFilterState {
    global?: string
    columns: Record<string, DataTableFilterValue>
}

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

selection
{ toggleRow: (row: T) => void; toggleAllRows: () => void; clearSelection: () => void; getSelectedRows: () => T[]; selectedRows: Readonly<ShallowRef<ReadonlySet<string | number>>>; isAllSelected: ComputedRef<boolean>; }
The table selection namespace, providing row-selection actions, selected-key state, and a method to read selected row data.
Details

Declared type

{ toggleRow: (row: T) => void; toggleAllRows: () => void; clearSelection: () => void; getSelectedRows: () => T[]; selectedRows: Readonly<ShallowRef<ReadonlySet<string | number>>>; isAllSelected: ComputedRef<boolean>; }

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

selection.toggleRow
(row: T) => void
Toggles selection for the specified row; selectable must be enabled.
Details

Declared type

(row: T) => void

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

selection.toggleAllRows
() => void
Toggles selection for all rows on the current display page; clearing preserves selections from other pages or filtered-out rows.
Details

Declared type

() => void

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

selection.clearSelection
() => void
Clears all selected row keys.
Details

Declared type

() => void

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

selection.getSelectedRows
() => T[]
Returns the full row data array for the current selection.
Details

Declared type

() => T[]

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

selection.selectedRows
Readonly
Readonly<ShallowRef<ReadonlySet<string | number>>>
The read-only shallow-reactive set of selected row keys.
Details

Declared type

Readonly<ShallowRef<ReadonlySet<string | number>>>

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

selection.isAllSelected
Readonly
ComputedRef<boolean>
A read-only computed state indicating whether all rows on the current display page are selected.
Details

Declared type

ComputedRef<boolean>

Literal values

  • false
  • true

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

pagination
{ goToPage: (page: number) => boolean; nextPage: () => boolean; previousPage: () => boolean; setPageSize: (size: number) => void; pageIndex: Readonly<Ref<number, number>>; pageCount: ComputedRef<number>; }
The table pagination namespace, containing page state and pagination control methods.
Details

Declared type

{ goToPage: (page: number) => boolean; nextPage: () => boolean; previousPage: () => boolean; setPageSize: (size: number) => void; pageIndex: Readonly<Ref<number, number>>; pageCount: ComputedRef<number>; }

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

pagination.goToPage
(page: number) => boolean
Navigates to the requested page, clamps it to the valid range, and returns whether the page changed.
Details

Declared type

(page: number) => boolean

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

pagination.nextPage
() => boolean
Attempts to move to the next page and returns whether the page changed.
Details

Declared type

() => boolean

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

pagination.previousPage
() => boolean
Attempts to move to the previous page and returns whether the page changed.
Details

Declared type

() => boolean

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

pagination.setPageSize
(size: number) => void
Sets the page size and resets the current page to the first page; invalid sizes are ignored.
Details

Declared type

(size: number) => void

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

pagination.pageIndex
Readonly
Readonly<Ref<number, number>>
The read-only reactive current page number, starting at 1.
Details

Declared type

Readonly<Ref<number, number>>

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

pagination.pageCount
Readonly
ComputedRef<number>
The read-only computed page count; it is at least 1 when there are no rows.
Details

Declared type

ComputedRef<number>

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

expand
{ toggleRow: (row: T) => void; isRowExpanded: (row: T) => boolean; expandedRowKeys: ShallowRef<Set<string | number>, Set<string | number>>; }
The table row-expansion namespace, providing toggle and query methods plus the expanded-key state.
Details

Declared type

{ toggleRow: (row: T) => void; isRowExpanded: (row: T) => boolean; expandedRowKeys: ShallowRef<Set<string | number>, Set<string | number>>; }

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

expand.toggleRow
(row: T) => void
Toggles expansion for the specified row and emits expand-change.
Details

Declared type

(row: T) => void

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

expand.isRowExpanded
(row: T) => boolean
Checks whether the specified row is currently expanded.
Details

Declared type

(row: T) => boolean

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

expand.expandedRowKeys
ShallowRef<Set<string | number>, Set<string | number>>
The shallow-reactive set containing the currently expanded row keys.
Details

Declared type

ShallowRef<Set<string | number>, Set<string | number>>

Source

DataTable.vue

packages/ui/src/components/data-table/DataTable.vue

DataTableColumnFilter

DataTableColumnFilter — Props
NameTypeDefaultDescription
column
Required
DataTableColumn<any>
—
The column definition for this filter control; its filterType and filterOptions determine the filter UI.
Details

Declared type

DataTableColumn<any>

Referenced types

DataTableColumn
Type definition — DataTableColumn
export interface DataTableColumn<T extends object = Record<string, unknown>> {
    id: string
    /** 函数签名已更新:回调参数从 DataTableColumn<T> 改为 DataTableColumnHeaderContext */
    header: string | ((ctx: DataTableColumnHeaderContext) => string)
    accessorKey?: keyof T & string
    accessorFn?: (row: T) => unknown
    cell?: (props: { row: T; value: unknown }) => VNode | string
    sortable?: boolean
    hidden?: boolean
    width?: number | 'auto'
    minWidth?: number
    maxWidth?: number
    align?: 'left' | 'center' | 'right'
    /** 固定列方向 */
    fixed?: 'left' | 'right'
    /** 列类型 */
    type?: 'default' | 'expand'
    /** 过滤器类型 */
    filterType?: 'text' | 'select' | 'multi-select' | 'date-range'
    /** 过滤可选项 */
    filterOptions?: Array<{ label: string; value: string | number }>
}

Default value details

Not declared
—

Source

DataTableColumnFilter.vue:20

packages/ui/src/components/data-table/DataTableColumnFilter.vue

filterState
Required
{ readonly global?: string | undefined; readonly columns: { readonly [x: string]: string | number | readonly (string | number)[] | { readonly start: string | null; readonly end: string | null; } | null | undefined; }; }
—
The current read-only filter state, used to display this column’s text, option, or date-range value.
Details

Declared type

{ readonly global?: string | undefined; readonly columns: { readonly [x: string]: string | number | readonly (string | number)[] | { readonly start: string | null; readonly end: string | null; } | null | undefined; }; }

Default value details

Not declared
—

Source

DataTableColumnFilter.vue:21

packages/ui/src/components/data-table/DataTableColumnFilter.vue

headerLabel
Required
string
—
The displayed column-header text used to label the filter control.
Details

Declared type

string

Default value details

Not declared
—

Source

DataTableColumnFilter.vue:22

packages/ui/src/components/data-table/DataTableColumnFilter.vue

DataTableColumnFilter — Events
NameSignature or typeDescription
@update:filterState
[state: DataTableFilterState]
Emits a state object containing only the current column change when its filter value changes; a null column value clears that column filter.
Details

Declared type

[state: DataTableFilterState]

Referenced types

DataTableFilterState
Type definition — DataTableFilterState
export interface DataTableFilterState {
    global?: string
    columns: Record<string, DataTableFilterValue>
}

Source

DataTableColumnFilter.vue

packages/ui/src/components/data-table/DataTableColumnFilter.vue

DataTableColumn Type ​

DataTableColumn Props ​

PropTypeDefaultDescription
idstring— (required)Column unique identifier
headerstring | ((ctx) => string)— (required)Column header text or render function
accessorKeykeyof T & string—Data field key
accessorFn(row: T) => unknown—Custom value accessor function
cell(props) => VNode | string—Custom cell render function
sortableboolean—Whether the column is sortable
hiddenboolean—Whether to hide the column
widthnumber | 'auto'—Column width
minWidthnumber—Minimum column width
maxWidthnumber—Maximum column width
align'left' | 'center' | 'right'—Column content alignment
fixed'left' | 'right'—Fixed column direction; offsets use the browser-rendered width. Set width when a stable width is needed.
type'default' | 'expand''default'Column type (expand for expand column)

Accessibility ​

The DataTable component follows the WAI-ARIA table pattern, providing the following accessibility support:

  • Uses semantic <table>, <thead>, <tbody>, <tr>, <th>, <td> elements
  • Sort state communicated to screen readers via aria-sort attribute
  • Selection state marked via aria-selected attribute on selected rows
  • Filter inputs and pagination controls provide appropriate aria-label
  • Keyboard navigation support: Tab key switches between interactive elements, Enter/Space triggers sorting and selection

FAQ ​

Q: Why isn't the selection state working after setting selectable?

A: Ensure the row-key prop is correctly set. row-key identifies the uniqueness of each row, and the selection feature depends on it to track selected rows. If row-key is not provided, selection will not work properly. It is recommended to use a unique field from the data, such as id.

Q: What is the execution order when sorting, filtering, and pagination are all enabled?

A: The component processes data internally in the order: "filter -> sort -> paginate". That is, data is first filtered by filter criteria, then sorted, and finally paginated. If programmatic APIs (like setGlobalFilter and toggleSort) are used simultaneously, the same processing order applies.

Q: How do I optimize table performance with large datasets?

A: When the data exceeds several hundred rows, it is recommended to enable virtual scrolling. By configuring :virtual-scroll="{ enabled: true }", the table will only render rows within the visible area, significantly reducing DOM node count. You can also set :dense="true" to compress row height, further improving information density within the visible area.

Brute force builds.