DataTable 数据表格
新粗野主义风格的数据表格组件,提供完整的排序、筛选、多选、分页和虚拟滚动功能。支持泛型数据源,通过 columns 配置驱动的列定义实现灵活的数据展示。
预览
姓名 | 邮箱 | 角色 | 状态 | |
|---|---|---|---|---|
| 张三 | zhangsan@example.com | 管理员 | 活跃 | |
| 李四 | lisi@example.com | 编辑 | 活跃 | |
| 王五 | wangwu@example.com | 查看者 | 未活跃 | |
| 赵六 | zhaoliu@example.com | 编辑 | 活跃 | |
| 孙七 | sunqi@example.com | 管理员 | 未活跃 |
安装
pnpm dlx brutx-vue@latest add data-table用法
基础用法
<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: '姓名',
accessorKey: 'name',
sortable: true,
},
{
id: 'email',
header: '邮箱',
accessorKey: 'email',
sortable: true,
},
{
id: 'role',
header: '角色',
accessorKey: 'role',
},
{
id: 'status',
header: '状态',
accessorKey: 'status',
align: 'center',
},
]
const data = ref<User[]>([
{ id: 1, name: '张三', email: 'zhangsan@example.com', role: '管理员', status: '活跃' },
{ id: 2, name: '李四', email: 'lisi@example.com', role: '编辑', status: '活跃' },
{ id: 3, name: '王五', email: 'wangwu@example.com', role: '访客', status: '未激活' },
])
</script>
<template>
<DataTable
:data="data"
:columns="columns"
:sortable="true"
row-key="id"
/>
</template>启用排序
<template>
<DataTable
:data="data"
:columns="columns"
:sortable="true"
row-key="id"
@sort="handleSort"
/>
</template>通过 sortable 属性启用排序,在列定义中设置 sortable: false 可禁用特定列的排序。点击表头可在升序 / 降序 / 默认 之间切换。
启用筛选
<template>
<DataTable
:data="data"
:columns="columns"
:filterable="true"
row-key="id"
@filter="handleFilter"
/>
</template>启用 filterable 后,表格上方会显示全局搜索输入框,对所有可见列进行模糊匹配。
启用选择
<template>
<DataTable
:data="data"
:columns="columns"
:selectable="true"
row-key="id"
@select="handleSelect"
/>
</template>启用 selectable 后,每行左侧会显示复选框,表头复选框支持全选 / 取消全选。选中行后底部会显示已选行数,并可导出 CSV。
启用分页
<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>分页器包含首页、上一页、下一页、末页按钮,以及每页条数选择器。
列筛选
支持在每一列头部添加 Popover 筛选器。支持文本搜索、单选(Select)、多选(Multi-Select)以及日期范围(Date Range)筛选。
date-range 筛选会将单元格中的 YYYY-MM-DD 字符串按本地日期解析,并把结束日期包含到当天 23:59:59.999。完整 datetime 字符串仍按浏览器原生 Date / ISO datetime 语义解析;如果数据需要跨时区一致,建议存储为 Date、时间戳,或带时区偏移的完整 ISO 字符串。
<script setup lang="ts">
const columns = [
{ id: 'name', header: '姓名', accessorKey: 'name', filterType: 'text' },
{
id: 'role',
header: '角色',
accessorKey: 'role',
filterType: 'select',
filterOptions: [
{ label: '管理员', value: '管理员' },
{ label: '编辑', value: '编辑' }
]
},
{
id: 'status',
header: '状态',
accessorKey: 'status',
filterType: 'multi-select',
filterOptions: [
{ label: '活跃', value: '活跃' },
{ label: '未激活', value: '未激活' }
]
},
{
id: 'date',
header: '入职日期',
accessorKey: 'date',
filterType: 'date-range'
}
]
</script>
<template>
<DataTable
:data="data"
:columns="columns"
:filterable="true"
row-key="id"
/>
</template>自定义单元格
<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: '姓名', accessorKey: 'name' },
{
id: 'status',
header: '状态',
accessorKey: 'status',
cell: ({ value }) => {
return h(Badge, { variant: value === '活跃' ? 'success' : 'danger' }, () => String(value))
},
},
]
</script>通过 cell 函数可自定义单元格渲染,支持返回 VNode 或字符串。也可使用具名插槽 #cell-{columnId} 进行渲染。
使用插槽
<template>
<DataTable
:data="data"
:columns="columns"
row-key="id"
>
<template #cell-status="{ row, value }">
<Badge :variant="value === '活跃' ? 'success' : 'danger'">
{{ value }}
</Badge>
</template>
<template #toolbar>
<Button variant="primary" size="sm">
添加用户
</Button>
</template>
<template #empty>
<div class="text-center py-8">
<p class="text-lg font-bold">暂无数据</p>
<p class="text-sm text-brutal-fg/60">点击上方按钮添加第一条记录</p>
</div>
</template>
</DataTable>
</template>加载状态
<template>
<DataTable
:data="data"
:columns="columns"
:loading="isLoading"
row-key="id"
/>
</template>设置 loading 为 true 时,表格上方会显示旋转加载动画遮罩。也可通过 loading 具名插槽自定义加载态内容。
尺寸
<template>
<!-- 小尺寸 + 紧凑密度,适合信息密集型表格 -->
<DataTable
:data="data"
:columns="columns"
:sortable="true"
size="sm"
:dense="true"
row-key="id"
/>
<!-- 大尺寸,适合展示型表格 -->
<DataTable
:data="data"
:columns="columns"
size="lg"
row-key="id"
/>
</template>size 控制字体大小与单元格纵向 padding(sm → py-2、default → py-3、lg → py-4);dense 进一步压缩行高至 py-1.5,与 size 正交,可单独或组合使用。
条纹控制
<template>
<!-- 默认开启条纹(偶数行 bg-brutal-muted/50) -->
<DataTable
:data="data"
:columns="columns"
row-key="id"
/>
<!-- 显式关闭条纹 -->
<DataTable
:data="data"
:columns="columns"
:striped="false"
row-key="id"
/>
</template>striped 默认 true,偶数行应用 bg-brutal-muted/50 形成奇偶交替。若需要纯净外观或配合自定义行背景,可设为 false。
粘性表头
<template>
<DataTable
:data="largeData"
:columns="columns"
:sticky-header="true"
row-key="id"
/>
</template>启用 stickyHeader 后,表头会在页面或外层垂直滚动容器滚动时停留在可视区域顶部。表头与表格主体保持横向滚动同步;虚拟滚动仍由其行滚动区域负责纵向滚动。
数据类型
DataTableColumn
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 列唯一标识,必填 |
header | string | ((ctx: DataTableColumnHeaderContext) => string) | 列标题,必填;函数形式接收 DataTableColumnHeaderContext 上下文 |
accessorKey | keyof T & string | 通过 key 访问行数据字段 |
accessorFn | (row: T) => unknown | 通过函数访问行数据值 |
cell | (props: { row: T; value: unknown }) => VNode | string | 自定义单元格渲染 |
sortable | boolean | 是否可排序,默认 true |
hidden | boolean | 是否隐藏 |
width | number | 'auto' | 列宽度 |
minWidth | number | 最小宽度 |
maxWidth | number | 最大宽度 |
align | 'left' | 'center' | 'right' | 对齐方式 |
filterType | 'text' | 'select' | 'multi-select' | 'date-range' | 筛选类型,开启后表头会显示对应筛选 Popover |
filterOptions | Array<{ label: string; value: any }> | 筛选可选项,供 select 和 multi-select 筛选使用 |
DataTableColumnHeaderContext
header 回调函数接收的上下文对象,用于在函数式表头中获取列的运行时状态。
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 当前列的 ID |
sortable | boolean | 当前列是否可排序 |
direction | 'asc' | 'desc' | null | 当前列的排序方向(null 表示未排序) |
accessorKey | PropertyKey | 当前列的 accessorKey(如果有) |
align | 'left' | 'center' | 'right' | 当前列的对齐方式 |
DataTableVirtualScroll
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | boolean | — | 是否启用虚拟滚动 |
rowHeight | number | 'auto' | 48 | 每行预估高度(像素),'auto' 为根据 DOM 自动测量动态高度(要求所有列必须显式配置宽度) |
DataTableFilterState
| 字段 | 类型 | 说明 |
|---|---|---|
global | string | 全局筛选关键字 |
columns | Record<string, any> | 按列 ID 索引的列级筛选值 |
程序化控制
DataTable 通过 defineExpose 暴露了排序、筛选、选择、分页四组方法与状态,可通过组件 ref 在父组件中直接调用,实现"工具栏外置"、"外部按钮触发排序"、"批量操作按钮"等场景。
<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: '姓名', accessorKey: 'name', sortable: true },
{ id: 'email', header: '邮箱', accessorKey: 'email' },
{ id: 'role', header: '角色', accessorKey: 'role' },
{ id: 'status', header: '状态', accessorKey: 'status' },
]
const data: User[] = [
{ id: 1, name: '张三', email: 'zhangsan@example.com', role: '管理员', status: '活跃' },
{ id: 2, name: '李四', email: 'lisi@example.com', role: '编辑', status: '未激活' },
{ id: 3, name: '王五', email: 'wangwu@example.com', role: '访客', status: '活跃' },
]
// 程序化触发按 name 升序
function sortByNameAsc() {
tableRef.value?.sort.toggleSort('name')
}
// 程序化设置全局筛选关键字
function filterByAdmin() {
tableRef.value?.filter.setGlobalFilter('管理员')
}
// 全选当前页
function selectAll() {
tableRef.value?.selection.toggleAllRows()
}
// 跳转到下一页
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">按姓名排序</Button>
<Button variant="default" size="sm" @click="filterByAdmin">筛选"管理员"</Button>
<Button variant="default" size="sm" @click="selectAll">全选当前页</Button>
<Button variant="default" size="sm" @click="goNextPage">下一页</Button>
</div>
<DataTable
ref="tableRef"
:data="data"
:columns="columns"
:sortable="true"
:filterable="true"
:selectable="true"
:paginated="true"
:page-size="2"
row-key="id"
/>
</template>暴露成员
通过组件 ref 可使用排序、筛选、选择、分页和行展开命名空间及其状态,完整成员清单见下方 API 参考。程序化调用时,sort.toggleSort 和 selection 中的状态修改方法不会发出 sort 或 select;筛选状态变化仍会发出 filter;pagination 方法不会发出 page-change 或 page-size-change;expand.toggleRow 会发出 expand-change。
API 参考
DataTable
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
class | string | undefined | — | 追加到表格根容器的自定义 CSS 类。 |
详情 | |||
data必填 | T[] | — | 要显示的行数据;泛型 T 会传递到列定义、行事件及编程接口。 |
详情 | |||
columns必填 | DataTableColumn<T>[] | — | 表格列定义,控制列头、取值、排序、筛选、渲染及列布局。 |
详情声明类型DataTableColumn<T>[] 关联类型 DataTableColumn 类型定义 — DataTableColumnexport 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 }>
}默认值详情
来源packages/ui/src/types/data-table.ts | |||
sortable | boolean | undefined | false | 启用可排序列的表头交互和排序数据处理;列可通过 sortable: false 单独关闭。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
filterable | boolean | undefined | false | 显示全局搜索输入框,并为声明 filterType 的列显示列筛选器。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
filterPlaceholder | string | undefined | undefined | 全局搜索输入框的占位文字及无障碍名称;未提供时使用当前语言的 dataTable.filterPlaceholder。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/types/data-table.ts | |||
selectable | boolean | undefined | false | 显示行选择框及表头全选框,并允许读取和导出选中行。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
paginated | boolean | undefined | false | 启用分页切片和分页控件。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
pageSize | number | undefined | 10 | 分页启用时每页显示的行数;未启用分页时数据不会按页切片。 |
详情声明类型number | undefined 默认值详情
来源packages/ui/src/types/data-table.ts | |||
pageSizeOptions | number[] | undefined | [10, 20, 50, 100]按实例调用工厂函数 | 分页控件中可选的每页行数。 |
详情声明类型number[] | undefined 默认值详情
来源packages/ui/src/types/data-table.ts | |||
loading | boolean | undefined | false | 显示加载遮罩和 loading 插槽内容。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
emptyMessage | string | undefined | — | 无数据状态的提示文本;未提供或为空字符串时使用当前语言的 dataTable.noData。 |
详情 | |||
rowKey必填 | keyof T | ((row: T) => string | number) | — | 提供行的唯一标识字段或取值函数;选中和展开行状态依赖解析后的字符串或数字键。 |
详情声明类型keyof T | ((row: T) => string | number) 默认值详情
来源packages/ui/src/types/data-table.ts | |||
rowClickable | boolean | undefined | false | 使行可通过鼠标点击或 Enter 键触发 row-click 事件。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
title | string | undefined | undefined | 未提供 header 插槽时显示在表格头部的标题。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/types/data-table.ts | |||
description | string | undefined | undefined | 未提供 header 插槽时显示在标题下方的说明文本。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/types/data-table.ts | |||
section | boolean | undefined | false | 为表格根容器启用受限宽度并居中布局。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
framed | boolean | undefined | true | 控制根容器边框、阴影和圆角;设为 false 时移除这些外框样式。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
virtualScroll | DataTableVirtualScroll | undefined | — | 配置行虚拟滚动;enabled 为真时启用,rowHeight 可为固定行高或 auto 动态测量。 |
详情声明类型DataTableVirtualScroll | undefined 关联类型 DataTableVirtualScroll 类型定义 — DataTableVirtualScrollexport interface DataTableVirtualScroll {
enabled?: boolean
rowHeight?: number | 'auto'
}默认值详情
来源packages/ui/src/types/data-table.ts | |||
size | "default" | "lg" | "sm" | undefined | "default" | 设置表格尺寸变体。 |
详情声明类型"default" | "lg" | "sm" | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
dense | boolean | undefined | false | 启用更紧凑的行和单元格间距。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
striped | boolean | undefined | true | 控制相邻数据行的条纹背景。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
stickyHeader | boolean | undefined | false | 页面或外层垂直滚动容器滚动时,将表头固定在可视区域顶部;横向滚动与表格主体同步。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
expandable | boolean | undefined | false | 显示行展开控制并允许呈现 expanded-row 插槽。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/types/data-table.ts | |||
expandRowKeys | Set<string | number> | undefined | undefined | 受控展开行键集合;键须与 rowKey 的解析结果一致,变更会同步内部展开状态。 |
详情声明类型Set<string | number> | undefined 默认值详情
来源packages/ui/src/types/data-table.ts | |||
spanMethod | ((params: DataTableSpanMethodParams<T>) => void | [number, number]) | undefined | undefined | 对当前显示行和可见列的每个单元格计算合并范围;返回 rowspan、colspan,或不返回以使用默认跨度。 |
详情声明类型((params: DataTableSpanMethodParams<T>) => void | [number, number]) | undefined 默认值详情
来源packages/ui/src/types/data-table.ts | |||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
@sort | [column: string, direction: "asc" | "desc" | null] | 用户通过可排序表头交互后发出列 ID 和方向;方向为 asc、desc 或 null。 |
详情声明类型[column: string, direction: "asc" | "desc" | null] 字面量
来源packages/ui/src/components/data-table/DataTable.vue | ||
@filter | [filters: DataTableFilterState] | 筛选状态变化时发出当前全局及列筛选状态。 |
详情声明类型[filters: DataTableFilterState] 关联类型 DataTableFilterState 类型定义 — DataTableFilterStateexport interface DataTableFilterState {
global?: string
columns: Record<string, DataTableFilterValue>
}来源packages/ui/src/components/data-table/DataTable.vue | ||
@select | [rows: T[]] | 用户切换行选择或当前页全选状态后发出所选行数据数组。 |
详情声明类型[rows: T[]] 来源packages/ui/src/components/data-table/DataTable.vue | ||
@page-change | [page: number] | 用户导航到不同页码后发出实际生效的页码;页码未变化时不发出。 |
详情声明类型[page: number] 来源packages/ui/src/components/data-table/DataTable.vue | ||
@page-size-change | [size: number] | 用户在分页控件中选择新的每页行数后发出该行数。 |
详情声明类型[size: number] 来源packages/ui/src/components/data-table/DataTable.vue | ||
@expand-change | [row: T, expanded: boolean] | 行展开状态切换时发出对应行数据和新的展开布尔值。 |
详情声明类型[row: T, expanded: boolean] 字面量
来源packages/ui/src/components/data-table/DataTable.vue | ||
@row-click | [row: T] | rowClickable 启用时,行被鼠标点击或按 Enter 激活后发出行数据;事件来自按钮、输入框、链接等交互元素时跳过。 |
详情声明类型[row: T] 来源packages/ui/src/components/data-table/DataTable.vue | ||
@export | [format: "csv" | "json", selectedRows?: T[] | undefined] | 表格导出控件操作时发出所选格式和当前选中行数组。 |
详情声明类型[format: "csv" | "json", selectedRows?: T[] | undefined] 字面量
来源packages/ui/src/components/data-table/DataTable.vue | ||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
#header | {} | 替换表格默认头部;未提供时根据 title 和 description 渲染标题区。 |
详情声明类型{}来源packages/ui/src/components/data-table/DataTable.vue | ||
#toolbar | {} | 全局筛选工具栏的扩展内容;启用 filterable 时显示在搜索输入框旁。 |
详情声明类型{}来源packages/ui/src/components/data-table/DataTable.vue | ||
#expanded-row | { row: T; index: number; } | 展开行的附加内容,作用域提供 row 和当前展示列表中的 index;仅在该行展开且 expandable 启用时渲染。 |
详情声明类型{ row: T; index: number; }来源packages/ui/src/components/data-table/DataTable.vue | ||
#empty | {} | 替换无数据状态内容;仅当没有可显示数据且未处于 loading 状态时渲染。 |
详情声明类型{}来源packages/ui/src/components/data-table/DataTable.vue | ||
#loading | {} | 替换加载遮罩内容;仅在 loading 为真时渲染。 |
详情声明类型{}来源packages/ui/src/components/data-table/DataTable.vue | ||
#footer | {} | 在表格及加载区域之后渲染的页脚扩展内容。 |
#cell-{columnId} | { row: T; value: unknown } | 为指定列提供自定义单元格内容;插槽名为 cell-{columnId},作用域提供当前行 row 和单元格值 value。
|
详情声明类型{ row: T; value: unknown }来源packages/ui/src/components/data-table/DataTable.vue | ||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
sort | { toggleSort: (columnId: string) => void; sortState: Readonly<Ref<{ readonly column: string; readonly direction: "asc" | "desc" | null; }, { readonly column: string; readonly direction: "asc" | "desc" | null; }>>; } | 表格排序命名空间,包含 toggleSort 方法和只读 sortState。 |
详情声明类型{ toggleSort: (columnId: string) => void; sortState: Readonly<Ref<{ readonly column: string; readonly direction: "asc" | "desc" | null; }, { readonly column: string; readonly direction: "asc" | "desc" | null; }>>; }来源packages/ui/src/components/data-table/DataTable.vue | ||
sort.toggleSort | (columnId: string) => void | 为给定列 ID 切换排序方向;需要 sortable 开启且列未禁用排序,顺序为升序、降序、取消。 |
详情声明类型(columnId: string) => void 来源packages/ui/src/components/data-table/DataTable.vue | ||
sort.sortState只读 | Readonly<Ref<{ readonly column: string; readonly direction: "asc" | "desc" | null; }, { readonly column: string; readonly direction: "asc" | "desc" | null; }>> | 只读响应式排序状态,包含当前列 ID 和 asc、desc 或 null 方向。 |
详情声明类型Readonly<Ref<{ readonly column: string; readonly direction: "asc" | "desc" | null; }, { readonly column: string; readonly direction: "asc" | "desc" | null; }>>来源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; } | 表格筛选命名空间,提供状态读取及设置全局或完整筛选条件的方法。 |
详情声明类型{ 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; }关联类型 DataTableFilterState 类型定义 — DataTableFilterStateexport interface DataTableFilterState {
global?: string
columns: Record<string, DataTableFilterValue>
}来源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; }; }>> | 只读响应式筛选状态,包含可选的 global 值和按列 ID 索引的 columns。 |
详情声明类型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; }; }>>来源packages/ui/src/components/data-table/DataTable.vue | ||
filter.setGlobalFilter | (value: string) => void | 设置全局搜索关键字。 |
详情声明类型(value: string) => void 来源packages/ui/src/components/data-table/DataTable.vue | ||
filter.setFilterState | (state: DataTableFilterState) => void | 用给定的 DataTableFilterState 更新完整筛选状态。 |
详情声明类型(state: DataTableFilterState) => void 关联类型 DataTableFilterState 类型定义 — DataTableFilterStateexport interface DataTableFilterState {
global?: string
columns: Record<string, DataTableFilterValue>
}来源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>; } | 表格选择命名空间,提供行选择操作、选中行键状态及读取选中行数据的方法。 |
详情声明类型{ toggleRow: (row: T) => void; toggleAllRows: () => void; clearSelection: () => void; getSelectedRows: () => T[]; selectedRows: Readonly<ShallowRef<ReadonlySet<string | number>>>; isAllSelected: ComputedRef<boolean>; }来源packages/ui/src/components/data-table/DataTable.vue | ||
selection.toggleRow | (row: T) => void | 切换指定行的选择状态;需要 selectable 开启。 |
详情声明类型(row: T) => void 来源packages/ui/src/components/data-table/DataTable.vue | ||
selection.toggleAllRows | () => void | 切换当前显示页所有行的选择状态;取消时保留其他页或筛选隐藏行的选择。 |
详情声明类型() => void 来源packages/ui/src/components/data-table/DataTable.vue | ||
selection.clearSelection | () => void | 清空全部已选行键。 |
详情声明类型() => void 来源packages/ui/src/components/data-table/DataTable.vue | ||
selection.getSelectedRows | () => T[] | 返回当前所选行对应的完整行数据数组。 |
详情声明类型() => T[] 来源packages/ui/src/components/data-table/DataTable.vue | ||
selection.selectedRows只读 | Readonly<ShallowRef<ReadonlySet<string | number>>> | 只读浅响应式集合,保存已选行键。 |
详情声明类型Readonly<ShallowRef<ReadonlySet<string | number>>> 来源packages/ui/src/components/data-table/DataTable.vue | ||
selection.isAllSelected只读 | ComputedRef<boolean> | 只读计算状态,表示当前显示页的全部行是否已选中。 |
详情声明类型ComputedRef<boolean> 字面量
来源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>; } | 表格分页命名空间,包含页码和页数状态以及分页控制方法。 |
详情声明类型{ goToPage: (page: number) => boolean; nextPage: () => boolean; previousPage: () => boolean; setPageSize: (size: number) => void; pageIndex: Readonly<Ref<number, number>>; pageCount: ComputedRef<number>; }来源packages/ui/src/components/data-table/DataTable.vue | ||
pagination.goToPage | (page: number) => boolean | 跳转到指定页;页码会限制在有效范围,并返回页码是否实际改变。 |
详情声明类型(page: number) => boolean 来源packages/ui/src/components/data-table/DataTable.vue | ||
pagination.nextPage | () => boolean | 尝试前往下一页,并返回页码是否实际改变。 |
详情声明类型() => boolean 来源packages/ui/src/components/data-table/DataTable.vue | ||
pagination.previousPage | () => boolean | 尝试前往上一页,并返回页码是否实际改变。 |
详情声明类型() => boolean 来源packages/ui/src/components/data-table/DataTable.vue | ||
pagination.setPageSize | (size: number) => void | 设置每页行数并将当前页重置为第一页;非法尺寸会被忽略。 |
详情声明类型(size: number) => void 来源packages/ui/src/components/data-table/DataTable.vue | ||
pagination.pageIndex只读 | Readonly<Ref<number, number>> | 只读响应式当前页码,从 1 开始。 |
详情声明类型Readonly<Ref<number, number>> 来源packages/ui/src/components/data-table/DataTable.vue | ||
pagination.pageCount只读 | ComputedRef<number> | 只读计算的总页数;没有行数据时至少为 1。 |
详情声明类型ComputedRef<number> 来源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>>; } | 表格行展开命名空间,提供切换、查询及读取已展开行键的方法和状态。 |
详情声明类型{ toggleRow: (row: T) => void; isRowExpanded: (row: T) => boolean; expandedRowKeys: ShallowRef<Set<string | number>, Set<string | number>>; }来源packages/ui/src/components/data-table/DataTable.vue | ||
expand.toggleRow | (row: T) => void | 切换指定行的展开状态并发出 expand-change 事件。 |
详情声明类型(row: T) => void 来源packages/ui/src/components/data-table/DataTable.vue | ||
expand.isRowExpanded | (row: T) => boolean | 查询指定行当前是否展开。 |
详情声明类型(row: T) => boolean 来源packages/ui/src/components/data-table/DataTable.vue | ||
expand.expandedRowKeys | ShallowRef<Set<string | number>, Set<string | number>> | 保存当前已展开行键的浅响应式集合。 |
详情声明类型ShallowRef<Set<string | number>, Set<string | number>> 来源packages/ui/src/components/data-table/DataTable.vue | ||
DataTableColumnFilter
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
column必填 | DataTableColumn<any> | — | 此筛选控件对应的列定义;其 filterType 和 filterOptions 决定筛选器控件。 |
详情声明类型DataTableColumn<any> 关联类型 DataTableColumn 类型定义 — DataTableColumnexport 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 }>
}默认值详情
来源packages/ui/src/components/data-table/DataTableColumnFilter.vue | |||
filterState必填 | { 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; }; }默认值详情
来源packages/ui/src/components/data-table/DataTableColumnFilter.vue | |||
headerLabel必填 | string | — | 用于构造筛选控件标题的列头显示文本。 |
详情声明类型string 默认值详情
来源packages/ui/src/components/data-table/DataTableColumnFilter.vue | |||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
@update:filterState | [state: DataTableFilterState] | 筛选值变化时发出只包含当前列增量的状态对象;列值为 null 表示清除该列筛选。 |
详情声明类型[state: DataTableFilterState] 关联类型 DataTableFilterState 类型定义 — DataTableFilterStateexport interface DataTableFilterState {
global?: string
columns: Record<string, DataTableFilterValue>
}来源packages/ui/src/components/data-table/DataTableColumnFilter.vue | ||
DataTableColumn 类型
DataTableColumn 属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
id | string | —(必填) | 列唯一标识 |
header | string | ((ctx) => string) | —(必填) | 列头文本或渲染函数 |
accessorKey | keyof T & string | — | 数据字段键 |
accessorFn | (row: T) => unknown | — | 自定义取值函数 |
cell | (props) => VNode | string | — | 自定义单元格渲染函数 |
sortable | boolean | — | 该列是否可排序 |
hidden | boolean | — | 是否隐藏该列 |
width | number | 'auto' | — | 列宽 |
minWidth | number | — | 最小列宽 |
maxWidth | number | — | 最大列宽 |
align | 'left' | 'center' | 'right' | — | 列内容对齐方式 |
fixed | 'left' | 'right' | — | 固定列方向,偏移量依据浏览器实际渲染宽度计算;需要稳定宽度时可同时设置 width |
type | 'default' | 'expand' | 'default' | 列类型(expand 为展开列) |
可访问性
DataTable 组件遵循 WAI-ARIA 表格模式,提供以下可访问性支持:
- 使用语义化的
<table>、<thead>、<tbody>、<tr>、<th>、<td>元素 - 排序状态通过
aria-sort属性通知屏幕阅读器 - 选择状态通过
aria-selected属性标记选中行 - 筛选输入框和分页控件均提供适当的
aria-label - 支持键盘导航:Tab 键在交互元素间切换,Enter/Space 键触发排序和选择
常见问题
Q: 为什么设置了 selectable 但选中状态没有生效?
A: 请确保正确设置了 row-key 属性。row-key 用于标识每一行的唯一性,选择功能依赖它来追踪选中行。如果没有提供 row-key,选择功能将无法正常工作。建议使用数据中具有唯一性的字段,如 id。
Q: 同时启用排序、筛选和分页时,它们之间的执行顺序是什么?
A: 组件内部按"筛选 → 排序 → 分页"的顺序处理数据。即先根据筛选条件过滤数据,再对过滤后的结果进行排序,最后进行分页。如果同时使用了程序化 API(如 setGlobalFilter 和 toggleSort),也会遵循相同的处理顺序。
Q: 数据量很大时如何优化表格性能?
A: 当数据量超过数百行时,建议启用虚拟滚动功能。通过配置 :virtual-scroll="{ enabled: true }" 属性,表格将只渲染可视区域内的行,大幅减少 DOM 节点数量。同时可以设置 :dense="true" 来压缩行高,进一步提升可视区域内的信息密度。