Table 表格
用于数据收集展示、分析整理和操作处理,适合中后台列表、配置项矩阵、数据明细和可批量处理的记录集合。
何时使用
- 需要展示结构化数据,并支持排序、筛选、分页、滚动或固定列。
- 需要对数据行进行选择、展开、拖拽、合并或汇总。
- 需要通过插槽或渲染函数定制表头、单元格、空态、分页两侧内容或内部表格元素。
基础用法
- 1
vue
<template>
<x-table :columns="columns" :data="data" />
</template>
<script setup lang="ts">
const columns = [
{ title: '名称', dataIndex: 'name' },
{ title: '类型', dataIndex: 'type' },
{ title: '状态', dataIndex: 'status' },
];
const data = [
{ key: '1', name: 'Button', type: '通用', status: '稳定' },
{ key: '2', name: 'Select', type: '表单', status: '维护中' },
{ key: '3', name: 'Table', type: '数据展示', status: '改造中' },
];
</script>声明式列
vue
<template>
<x-table :data="data" :pagination="false">
<x-table-column title="名称" data-index="name" />
<x-table-column title="状态" data-index="status" />
</x-table>
</template>
<script setup lang="ts">
const data = [
{ key: '1', name: 'Button', status: '稳定' },
{ key: '2', name: 'Table', status: '维护中' },
];
</script>尺寸和边框
vue
<template>
<x-table :columns="columns" :data="data" size="small" :pagination="false" />
<x-table
:columns="columns"
:data="data"
size="mini"
:bordered="{ wrapper: true, cell: true }"
:pagination="false"
/>
</template>行选择器
- 1
- 2
vue
<template>
<x-table
v-model:selected-keys="selectedKeys"
:columns="columns"
:data="data"
:row-selection="{ type: 'checkbox', showCheckedAll: true, onlyCurrent: false }"
:pagination="{ pageSize: 3 }"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const selectedKeys = ref(['1', '2']);
</script>单选
vue
<template>
<x-table
v-model:selected-keys="selectedKeys"
:columns="columns"
:data="data"
:row-selection="{ type: 'radio' }"
:pagination="false"
/>
</template>展开行
vue
<template>
<x-table
v-model:expanded-keys="expandedKeys"
:columns="columns"
:data="data"
:expandable="{ title: '展开', width: 72 }"
>
<template #expand-row="{ record }">
{{ record.expand || `${record.name} 暂无额外说明。` }}
</template>
</x-table>
</template>树形数据
vue
<template>
<x-table
:columns="columns"
:data="data"
:default-expanded-keys="['1']"
:pagination="false"
/>
</template>排序和筛选
vue
<template>
<x-table
:columns="columns"
:data="data"
:filter-icon-align-left="alignLeft"
@change="handleChange"
/>
</template>
<script setup lang="ts">
const columns = [
{
title: '姓名',
dataIndex: 'name',
sortable: { sortDirections: ['ascend', 'descend'] },
},
{
title: '薪资',
dataIndex: 'salary',
filterable: {
filters: [{ text: '20000 以上', value: '20000' }],
filter: (values, record) => values.some((value) => record.salary > Number(value)),
multiple: true,
},
},
];
</script>分组表头、滚动和固定列
vue
<template>
<x-table
:columns="columns"
:data="data"
:scroll="{ x: 900, y: 220 }"
:pagination="false"
/>
</template>单元格合并
vue
<template>
<x-table
:columns="columns"
:data="data"
:span-method="spanMethod"
:bordered="{ wrapper: true, cell: true }"
/>
</template>
<script setup lang="ts">
const spanMethod = ({ rowIndex, columnIndex }) => {
if (rowIndex === 1 && columnIndex === 1) {
return { rowspan: 2, colspan: 2 };
}
};
</script>总结行
vue
<template>
<x-table
:columns="columns"
:data="data"
:summary="summary"
summary-text="合计"
/>
</template>
<script setup lang="ts">
const summary = ({ data }) => {
const total = data.reduce((acc, item) => {
acc.salary += item.salary;
return acc;
}, { name: '合计', salary: 0 });
return [total];
};
</script>调整列宽
vue
<template>
<x-table
:columns="columns"
:data="data"
column-resizable
:bordered="{ wrapper: true, cell: true }"
/>
</template>拖拽排序
vue
<template>
<x-table
:columns="columns"
:data="data"
:draggable="{ type: 'handle', width: 40 }"
@change="handleChange"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const data = ref([...]);
const handleChange = (nextData, extra) => {
if (extra.type === 'drag') data.value = nextData;
};
</script>虚拟列表
vue
<template>
<x-table
:columns="columns"
:data="data"
:virtual-list-props="{ height: 260, fixedSize: true, estimatedSize: 48 }"
:pagination="false"
/>
</template>自定义渲染和插槽
vue
<template>
<x-table :columns="columns" :data="data">
<template #nameCell="{ record }">
<strong>{{ record.name }}</strong>
</template>
</x-table>
</template>空态和加载
vue
<template>
<x-table :columns="columns" :data="[]" :pagination="false">
<template #empty>暂无匹配数据</template>
</x-table>
<x-table :columns="columns" :data="data" loading />
</template>事件回调
vue
<template>
<x-table
:columns="columns"
:data="data"
@row-click="handleRowClick"
@cell-click="handleCellClick"
@header-click="handleHeaderClick"
/>
</template>按需导入
ts
import { Table, TableColumn } from 'x-next';Table Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
columns | 表格列配置 | TableColumnData[] | [] |
data | 表格数据 | TableData[] | [] |
bordered | 是否显示边框 | boolean | TableBorder | false |
hoverable | 是否显示行悬浮效果 | boolean | true |
stripe | 是否显示斑马纹 | boolean | false |
size | 表格尺寸 | 'mini' | 'small' | 'medium' | 'large' | 'large' |
tableLayoutFixed | 是否使用 fixed 表格布局 | boolean | false |
loading | 是否加载中,object 会透传给 Spin | boolean | object | false |
rowSelection | 行选择配置 | TableRowSelection | - |
expandable | 展开行配置 | TableExpandable | - |
scroll | 滚动配置 | { x?: number | string; y?: number | string; minWidth?: number | string; maxHeight?: number | string } | - |
pagination | 分页配置,传 false 可关闭分页 | boolean | PaginationProps | true |
pagePosition | 分页位置 | 'tl' | 'top' | 'tr' | 'bl' | 'bottom' | 'br' | 'br' |
indentSize | 树形表格缩进距离 | number | 16 |
rowKey | 表格行 key 字段 | string | 'key' |
showHeader | 是否显示表头 | boolean | true |
virtualListProps | 虚拟列表配置,传入后开启虚拟滚动 | VirtualListProps | - |
spanMethod | 单元格合并方法 | (data) => { rowspan?: number; colspan?: number } | void | - |
spanAll | 合并方法索引是否包含操作列 | boolean | false |
components | 自定义内部操作列组织方式 | TableComponents | - |
loadMore | 树形数据懒加载函数 | (record, done) => void | - |
filterIconAlignLeft | 筛选图标是否左对齐 | boolean | false |
hideExpandButtonOnEmpty | 子树为空时是否隐藏展开按钮 | boolean | false |
rowClass | 行 class,支持函数 | string | any[] | object | ((record, rowIndex) => any) | - |
draggable | 拖拽排序配置 | TableDraggable | - |
rowNumber | 行号配置,当前源码保留但文档不建议优先使用 | boolean | object | - |
columnResizable | 是否允许调整列宽 | boolean | false |
summary | 是否显示总结行,或自定义总结数据 | boolean | ((params) => TableData[]) | - |
summaryText | 默认总结行首列文字 | string | 'Summary' |
summarySpanMethod | 总结行单元格合并方法 | (data) => { rowspan?: number; colspan?: number } | void | - |
selectedKeys | 已选择行 key,受控模式 | (string | number)[] | - |
defaultSelectedKeys | 默认已选择行 key | (string | number)[] | - |
expandedKeys | 已展开行 key,受控模式 | (string | number)[] | - |
defaultExpandedKeys | 默认展开行 key | (string | number)[] | - |
defaultExpandAllRows | 是否默认展开全部行 | boolean | false |
stickyHeader | 是否开启表头吸顶,数字表示 top 偏移 | boolean | number | false |
scrollbar | 是否使用自定义滚动条,或传入 Scrollbar 配置 | boolean | ScrollbarProps | true |
showEmptyTree | 是否展示空子树 | boolean | false |
Table Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
update:selectedKeys | 选中行变化时触发 | rowKeys |
update:expandedKeys | 展开行变化时触发 | rowKeys |
expand | 点击展开行时触发 | rowKey, record |
expanded-change | 展开行变化时触发 | rowKeys |
select | 点击行选择器时触发 | rowKeys, rowKey, record |
select-all | 点击全选选择器时触发 | checked |
selection-change | 已选择行变化时触发 | rowKeys |
sorter-change | 排序规则变化时触发 | dataIndex, direction |
filter-change | 筛选项变化时触发 | dataIndex, filteredValues |
page-change | 分页页码变化时触发 | page |
page-size-change | 每页数量变化时触发 | pageSize |
change | 分页、排序、筛选、拖拽变化时触发 | data, extra, currentData |
cell-mouse-enter | 鼠标进入单元格时触发 | record, column, event |
cell-mouse-leave | 鼠标离开单元格时触发 | record, column, event |
cell-click | 点击单元格时触发 | record, column, event |
row-click | 点击行时触发 | record, event |
header-click | 点击表头时触发 | column, event |
column-resize | 调整列宽时触发 | dataIndex, width |
row-dblclick | 双击行时触发 | record, event |
cell-dblclick | 双击单元格时触发 | record, column, event |
row-contextmenu | 右击行时触发 | record, event |
cell-contextmenu | 右击单元格时触发 | record, column, event |
Table Methods
| 方法名 | 说明 | 参数 |
|---|---|---|
selectAll | 设置全选状态 | checked?: boolean |
select | 设置指定行选择状态 | rowKey, checked?: boolean |
expandAll | 设置全部展开状态 | checked?: boolean |
expand | 设置指定行展开状态 | rowKey, checked?: boolean |
resetFilters | 重置列筛选器到默认值 | dataIndex?: string | string[] |
clearFilters | 清空列筛选器 | dataIndex?: string | string[] |
resetSorters | 重置列排序到默认值 | - |
clearSorters | 清空列排序 | - |
Table Slots
| 插槽名 | 说明 | 参数 |
|---|---|---|
default | TableColumn 声明式列,或自定义 table 内容 | - |
columns | TableColumn 声明式列 | - |
expand-icon | 自定义展开图标 | { expanded, record } |
expand-row | 展开行内容 | { record } |
footer | 表格底部内容 | - |
drag-handle-icon | 拖拽手柄图标 | - |
tbody | 自定义 tbody 元素 | - |
tr | 自定义 tr 元素 | { record, rowIndex } |
td | 自定义 td 元素 | { record, column, rowIndex } |
pagination-left | 分页器左侧内容 | - |
pagination-right | 分页器右侧内容 | - |
summary-cell | 总结行单元格 | { column, record, rowIndex } |
empty | 空态内容 | - |
thead | 自定义 thead 元素 | - |
th | 自定义 th 元素 | { column } |
TableColumn Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
dataIndex | 列字段名 | string | - |
title | 列标题 | string | - |
width | 列宽 | number | - |
minWidth | 最小列宽 | number | - |
align | 对齐方式 | 'left' | 'center' | 'right' | - |
fixed | 固定位置 | 'left' | 'right' | - |
ellipsis | 是否显示省略 | boolean | false |
tooltip | 省略时是否显示提示,或 Tooltip 配置 | boolean | object | false |
sortable | 排序配置 | TableSortable | - |
filterable | 筛选配置 | TableFilterable | - |
cellClass | 单元格 class | ClassName | - |
headerCellClass | 表头单元格 class | ClassName | - |
bodyCellClass | 内容单元格 class | ClassName | ((record) => ClassName) | - |
summaryCellClass | 总结单元格 class | ClassName | ((record) => ClassName) | - |
cellStyle | 单元格样式 | CSSProperties | - |
headerCellStyle | 表头单元格样式 | CSSProperties | - |
bodyCellStyle | 内容单元格样式 | CSSProperties | ((record) => CSSProperties) | - |
summaryCellStyle | 总结单元格样式 | CSSProperties | ((record) => CSSProperties) | - |
index | 手动指定列序号,通常无需使用 | number | - |
TableColumn Slots
| 插槽名 | 说明 | 参数 |
|---|---|---|
cell | 单元格内容 | { record, column, rowIndex } |
title | 表头内容 | - |
filter-content | 自定义筛选弹层内容 | { filterValue, setFilterValue, handleFilterConfirm, handleFilterReset } |
filter-icon | 自定义筛选图标 | - |
类型说明
| 类型 | 说明 |
|---|---|
TableData | 行数据,默认用 key 作为唯一标识,可包含 children、expand、disabled、isLeaf |
TableSortable | 排序配置,包含 sortDirections、sorter、sortOrder、defaultSortOrder |
TableFilterable | 筛选配置,包含 filters、filter、multiple、filteredValue、defaultFilteredValue、renderContent、icon、triggerProps、alignLeft、slotName |
TableRowSelection | 行选择配置,包含 type、selectedRowKeys、defaultSelectedRowKeys、showCheckedAll、title、width、fixed、checkStrictly、onlyCurrent |
TableExpandable | 展开行配置,包含 expandedRowKeys、defaultExpandedRowKeys、defaultExpandAllRows、expandedRowRender、icon、title、width、fixed |
TableDraggable | 拖拽配置,包含 type、title、width、fixed |
TableChangeExtra | change 事件附加信息,包含 type、page、pageSize、sorter、filters、dragTarget |
元素插槽说明
tbody、thead、tr、td、th 是内部元素插槽。传入时建议只提供单一空元素或单一组件,让 Table 把原有 children、class、style 和事件合并到该元素上。若传入的元素内部自行写死内容,可能覆盖表格原本的行、列和事件结构。
已知限制
- 拖拽排序仍是鼠标 / 触摸优先能力,暂未提供键盘拖拽替代路径。
- 非受控分页下筛选、排序和每页数量变化会自动回到第一页;受控分页需要业务同步
pagination.current。 rowNumber在源码中保留,但当前文档不推荐作为稳定公开能力使用。