DataTable
A data table with sorting, selection, and expandable rows.
Usage
Basic
Loading demo...
Row Selection
selectable adds a selection column; v-model:selected-keys syncs the selected rows.
Loading demo...
Skeleton Loading
loadingVariant="skeleton" draws placeholder rows while there are none; a refresh of existing rows shows only a bar under the header.
Loading demo...
Expandable Rows
expandable adds a leading toggle column; the #expanded slot renders the detail under a row.
Loading demo...
Records Table
A wide layout with a pinned header and footer, a frozen first column, and selection highlighting; cells compose TxTag, TxDotIndicator, and TxCellLink.
Loading demo...
Data Operations Panel
TxPagination pages the list, and TxSkeleton / TxLayoutSkeleton preview the loading state.
Loading demo...
Best Practices
- Pass a stable
rowKeyfor business lists; to keep selection across pages, driveselectedKeyswith business ids, not default indexes. - For server-loaded lists, use
loadingVariant="skeleton"withskeletonRowsset to the page size; keep the defaultoverlayfor short local waits. - Give fixed columns numeric px
width/minWidth, and keep one horizontal scroller:scrollX, or an outeroverflow-x: auto. - A pinned header or footer needs
maxHeightor a scrolling ancestor; don't nest the table inTxScroll's default mode, whose transform scrolling disables sticky. - Sort on comparable fields such as timestamps or ranks, never on formatted relative-time text.
API Reference
Props
| Name | Type | Default | Description |
|---|---|---|---|
columns | DataTableColumn[] | [] | Column config. |
data | any[] | [] | Data source. |
rowKey | keyof T | (row: T, index: number) => string | number | index | Unique row key. |
loading | boolean | false | Loading state. |
loadingVariant | 'overlay' | 'skeleton' | 'overlay' | overlay veils the table with a spinner; skeleton draws placeholder rows, or only a bar when rows exist. |
skeletonRows | number | 5 | Placeholder rows before the first data lands; match the page size so nothing moves. |
emptyText | string | 'No data' | Empty text. |
striped | boolean | false | Zebra rows. |
bordered | boolean | false | Show borders. |
hover | boolean | true | Hover highlight. |
interactiveRows | boolean | false | Makes rows focusable so Enter / Space fire rowClick; on automatically with a rowClick listener. |
selectable | boolean | false | Adds a selection column. |
selectedKeys | Array<string | number> | [] | Keys of the selected rows. |
expandable | boolean | false | Adds a leading toggle column; an expanded row renders a detail row beneath it. |
defaultExpandedKeys | Array<string | number> | [] | Initial expanded rows when uncontrolled; expandedKeys wins if both are passed. |
expandedKeys | Array<string | number> | - | Controlled expanded rows, bound with v-model:expanded-keys. |
rowExpandable | (row, index) => boolean | - | Per-row gate for expanding; a rejected row keeps an empty leading cell. |
expandLabel | string | 'Expand row' | Accessible name of a closed toggle. |
collapseLabel | string | 'Collapse row' | Accessible name of an open toggle. |
defaultSort | { key: string; order: 'asc' | 'desc' | null } | null | Initial sort when uncontrolled; pass either this or sort. |
sort | { key: string; order: 'asc' | 'desc' | null } | null | - | Controlled sort; null means unsorted. |
sortOnClient | boolean | true | Sorts locally; set false for remote sorting, which only emits. |
sortCycle | 'tri' | 'bi' | 'tri' | tri: ascending → descending → unsorted; bi alternates and never unsorts. |
tableLayout | 'auto' | 'fixed' | 'auto' | Native table-layout; use fixed when column widths must stay stable. |
nowrap | boolean | false | Prevents wrapping in every header and cell. |
maxHeight | string | number | - | Caps the height and scrolls the table vertically; what sticky rows stick to. |
scrollX | boolean | false | Scrolls horizontally inside the component; for wide tables with fixed columns. |
stickyHeader | boolean | false | Pins the header row. |
stickyFooter | boolean | false | Pins the summary row. |
rowClass | (row, index) => string | string[] | Record<string, boolean> | - | Extra classes per row, such as a tint by state. |
highlightSelected | boolean | false | Tints selected rows. |
Events
| Event | Payload | Description |
|---|---|---|
update:selectedKeys | (keys) | Selection update. |
selectionChange | (keys) | Selection change. |
update:expandedKeys | (keys) | Expansion update; fires in controlled and uncontrolled modes. |
expand | ({ row, index, expanded }) | A row was expanded or collapsed. |
sortChange | (sort) | Sort change. |
update:sort | (sort) | Sort change; fires in controlled and uncontrolled modes. |
rowClick | ({ row, index }) | Row click. |
Slots
| Name | Description |
|---|---|
header-<columnKey> | Custom header; receives { column, sorted, order, toggle }, where toggle advances the sort cycle. |
cell-<columnKey> | Custom cell; receives { row, column, value, index }. |
expanded | Detail of an expanded row, spanning every column; receives { row, index }. |
footer | The whole summary row of your own <td>s, which can span columns. Any footer slot renders a <tfoot>. |
footer-<columnKey> | One summary cell per column; receives { column, data }. footer wins when both exist. |
empty | Empty state when there are no rows and loading=false. |
DataTableColumn
| Field | Type | Description |
|---|---|---|
key | string | Column key. |
title | string | Header title. |
dataIndex | string | Data field. |
width | string | number | Column width. |
minWidth | string | number | Minimum column width. |
maxWidth | string | number | Maximum column width. |
auto | boolean | Forces the column width to auto. |
fixed | boolean | 'left' | 'right' | Sticky side; true means 'left'. Left offsets already include the toggle and selection columns. |
nowrap | boolean | Prevents wrapping in this column. |
align | 'left' | 'center' | 'right' | Alignment. |
sortable | boolean | Sortable. |
sorter | (a, b) => number | Custom sorter. |
format | (value, row, index) => string | Cell formatter. |
headerClass | string | Header class. |
cellClass | string | Cell class. |
Overview
- Passing
sortorexpandedKeys(evennullor[]) makes it controlled: the table only emits updates and renders what the parent sends back. - Sortable headers carry
scope="col"andaria-sort; click, Enter, and Space step throughsortCycle. - On a partial selection the select-all box is
indeterminate(aria-checked="mixed"); clicks in the selection and toggle cells never firerowClick. loadingsetsaria-busyon the<table>, and the empty state stays hidden while loading.- Placeholder rows are
aria-hiddenand as tall as a one-line row; the refresh bar holds still under reduced motion. stickyHeader,stickyFooter, ormaxHeightswitches toborder-collapse: separate. The last row has no bottom rule; the rule above atfootstays.
Technologies
- The skeleton variant renders
TxSkeleton. The on-demand style plugin loads its sheet; when importing styles by hand, add@talex-touch/tuffex/skeleton/style.css. - Source:
packages/tuffex/packages/components/src/data-table/.
查看源码
packages/tuffex/packages/components/src/data-table/index.ts
Customization
| CSS variable | Used for |
|---|---|
--tx-data-table-row-hover-bg | Row hover fill. |
--tx-data-table-row-selected-bg | Selected-row fill under highlightSelected. |
.records-shell {
--tx-data-table-row-hover-bg: var(--tx-bui-hover);
--tx-data-table-row-selected-bg: color-mix(in srgb, var(--tx-bui-accent) 7%, var(--tx-bui-surface));
}