Skip to content

Table 表格

用于数据收集展示、分析整理和操作处理,适合中后台列表、配置项矩阵、数据明细和可批量处理的记录集合。

何时使用

  • 需要展示结构化数据,并支持排序、筛选、分页、滚动或固定列。
  • 需要对数据行进行选择、展开、拖拽、合并或汇总。
  • 需要通过插槽或渲染函数定制表头、单元格、空态、分页两侧内容或内部表格元素。

基础用法

名称类型状态
Button通用稳定
Select表单维护中
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>

尺寸和边框

规格说明
large默认尺寸
small紧凑展示
规格说明
large默认尺寸
small紧凑展示
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>

行选择器

姓名薪资城市邮箱
Jane Doe23000Londonjane.doe@example.com
Alisa Ross25000Parisalisa.ross@example.com
Kevin Sandra22000Londonkevin.sandra@example.com
  • 1
  • 2
当前选中: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>

单选

姓名薪资城市邮箱
Jane Doe23000Londonjane.doe@example.com
Alisa Ross25000Parisalisa.ross@example.com
Kevin Sandra22000Londonkevin.sandra@example.com
Ed Hellen17000Tokyoed.hellen@example.com
William Smith27000Londonwilliam.smith@example.com
Nina Brown30000Parisnina.brown@example.com
vue
<template>
  <x-table
    v-model:selected-keys="selectedKeys"
    :columns="columns"
    :data="data"
    :row-selection="{ type: 'radio' }"
    :pagination="false"
  />
</template>

展开行

展开姓名薪资城市邮箱
Jane Doe23000Londonjane.doe@example.com
负责组件库基础能力和设计规范维护。
Alisa Ross25000Parisalisa.ross@example.com
Kevin Sandra22000Londonkevin.sandra@example.com
Ed Hellen17000Tokyoed.hellen@example.com
William Smith27000Londonwilliam.smith@example.com
Nina Brown30000Parisnina.brown@example.com
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>

树形数据

名称类型状态
数据录入表单稳定
Input表单稳定
Select表单维护中
数据展示展示改造中
vue
<template>
  <x-table
    :columns="columns"
    :data="data"
    :default-expanded-keys="['1']"
    :pagination="false"
  />
</template>

排序和筛选

姓名
薪资
城市
邮箱
Jane Doe23000Londonjane.doe@example.com
Alisa Ross25000Parisalisa.ross@example.com
Kevin Sandra22000Londonkevin.sandra@example.com
Ed Hellen17000Tokyoed.hellen@example.com
William Smith27000Londonwilliam.smith@example.com
Nina Brown30000Parisnina.brown@example.com
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>

分组表头、滚动和固定列

用户工作信息状态
姓名城市薪资邮箱
Jane DoeLondon23000jane.doe@example.com跟进中
Alisa RossParis25000alisa.ross@example.com跟进中
Kevin SandraLondon22000kevin.sandra@example.com跟进中
Ed HellenTokyo17000ed.hellen@example.com跟进中
William SmithLondon27000william.smith@example.com高绩效
Nina BrownParis30000nina.brown@example.com高绩效
vue
<template>
  <x-table
    :columns="columns"
    :data="data"
    :scroll="{ x: 900, y: 220 }"
    :pagination="false"
  />
</template>

单元格合并

姓名薪资城市邮箱
Jane Doe23000Londonjane.doe@example.com
Alisa Ross25000alisa.ross@example.com
Kevin Sandrakevin.sandra@example.com
Ed Hellen17000Tokyoed.hellen@example.com
William Smith27000Londonwilliam.smith@example.com
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>

总结行

姓名薪资项目数缺陷数
Jane Doe2300042
Alisa Ross2500051
Kevin Sandra2200034
Ed Hellen1700023
合计870001410
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>

调整列宽

姓名薪资城市邮箱
Jane Doe23000Londonjane.doe@example.com
Alisa Ross25000Parisalisa.ross@example.com
Kevin Sandra22000Londonkevin.sandra@example.com
Ed Hellen17000Tokyoed.hellen@example.com
William Smith27000Londonwilliam.smith@example.com
Nina Brown30000Parisnina.brown@example.com
vue
<template>
  <x-table
    :columns="columns"
    :data="data"
    column-resizable
    :bordered="{ wrapper: true, cell: true }"
  />
</template>

拖拽排序

姓名薪资城市邮箱
Jane Doe23000Londonjane.doe@example.com
Alisa Ross25000Parisalisa.ross@example.com
Kevin Sandra22000Londonkevin.sandra@example.com
Ed Hellen17000Tokyoed.hellen@example.com
William Smith27000Londonwilliam.smith@example.com
等待拖拽
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>

虚拟列表

编号任务状态负责人
1任务 1待处理Jane
2任务 2处理中Alisa
3任务 3已完成Kevin
4任务 4待处理Ed
5任务 5处理中Jane
6任务 6已完成Alisa
7任务 7待处理Kevin
8任务 8处理中Ed
9任务 9已完成Jane
10任务 10待处理Alisa
11任务 11处理中Kevin
12任务 12已完成Ed
13任务 13待处理Jane
14任务 14处理中Alisa
15任务 15已完成Kevin
16任务 16待处理Ed
17任务 17处理中Jane
18任务 18已完成Alisa
19任务 19待处理Kevin
20任务 20处理中Ed
21任务 21已完成Jane
22任务 22待处理Alisa
23任务 23处理中Kevin
24任务 24已完成Ed
25任务 25待处理Jane
26任务 26处理中Alisa
27任务 27已完成Kevin
28任务 28待处理Ed
29任务 29处理中Jane
30任务 30已完成Alisa
vue
<template>
  <x-table
    :columns="columns"
    :data="data"
    :virtual-list-props="{ height: 260, fixedSize: true, estimatedSize: 48 }"
    :pagination="false"
  />
</template>

自定义渲染和插槽

组件名称状态类型
Button稳定通用
Select维护中表单
Table改造中数据展示
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>

事件回调

姓名薪资城市邮箱
Jane Doe23000Londonjane.doe@example.com
Alisa Ross25000Parisalisa.ross@example.com
Kevin Sandra22000Londonkevin.sandra@example.com
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 | TableBorderfalse
hoverable是否显示行悬浮效果booleantrue
stripe是否显示斑马纹booleanfalse
size表格尺寸'mini' | 'small' | 'medium' | 'large''large'
tableLayoutFixed是否使用 fixed 表格布局booleanfalse
loading是否加载中,object 会透传给 Spinboolean | objectfalse
rowSelection行选择配置TableRowSelection-
expandable展开行配置TableExpandable-
scroll滚动配置{ x?: number | string; y?: number | string; minWidth?: number | string; maxHeight?: number | string }-
pagination分页配置,传 false 可关闭分页boolean | PaginationPropstrue
pagePosition分页位置'tl' | 'top' | 'tr' | 'bl' | 'bottom' | 'br''br'
indentSize树形表格缩进距离number16
rowKey表格行 key 字段string'key'
showHeader是否显示表头booleantrue
virtualListProps虚拟列表配置,传入后开启虚拟滚动VirtualListProps-
spanMethod单元格合并方法(data) => { rowspan?: number; colspan?: number } | void-
spanAll合并方法索引是否包含操作列booleanfalse
components自定义内部操作列组织方式TableComponents-
loadMore树形数据懒加载函数(record, done) => void-
filterIconAlignLeft筛选图标是否左对齐booleanfalse
hideExpandButtonOnEmpty子树为空时是否隐藏展开按钮booleanfalse
rowClass行 class,支持函数string | any[] | object | ((record, rowIndex) => any)-
draggable拖拽排序配置TableDraggable-
rowNumber行号配置,当前源码保留但文档不建议优先使用boolean | object-
columnResizable是否允许调整列宽booleanfalse
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是否默认展开全部行booleanfalse
stickyHeader是否开启表头吸顶,数字表示 top 偏移boolean | numberfalse
scrollbar是否使用自定义滚动条,或传入 Scrollbar 配置boolean | ScrollbarPropstrue
showEmptyTree是否展示空子树booleanfalse

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

插槽名说明参数
defaultTableColumn 声明式列,或自定义 table 内容-
columnsTableColumn 声明式列-
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是否显示省略booleanfalse
tooltip省略时是否显示提示,或 Tooltip 配置boolean | objectfalse
sortable排序配置TableSortable-
filterable筛选配置TableFilterable-
cellClass单元格 classClassName-
headerCellClass表头单元格 classClassName-
bodyCellClass内容单元格 classClassName | ((record) => ClassName)-
summaryCellClass总结单元格 classClassName | ((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 作为唯一标识,可包含 childrenexpanddisabledisLeaf
TableSortable排序配置,包含 sortDirectionssortersortOrderdefaultSortOrder
TableFilterable筛选配置,包含 filtersfiltermultiplefilteredValuedefaultFilteredValuerenderContenticontriggerPropsalignLeftslotName
TableRowSelection行选择配置,包含 typeselectedRowKeysdefaultSelectedRowKeysshowCheckedAlltitlewidthfixedcheckStrictlyonlyCurrent
TableExpandable展开行配置,包含 expandedRowKeysdefaultExpandedRowKeysdefaultExpandAllRowsexpandedRowRendericontitlewidthfixed
TableDraggable拖拽配置,包含 typetitlewidthfixed
TableChangeExtrachange 事件附加信息,包含 typepagepageSizesorterfiltersdragTarget

元素插槽说明

tbodytheadtrtdth 是内部元素插槽。传入时建议只提供单一空元素或单一组件,让 Table 把原有 children、class、style 和事件合并到该元素上。若传入的元素内部自行写死内容,可能覆盖表格原本的行、列和事件结构。

已知限制

  • 拖拽排序仍是鼠标 / 触摸优先能力,暂未提供键盘拖拽替代路径。
  • 非受控分页下筛选、排序和每页数量变化会自动回到第一页;受控分页需要业务同步 pagination.current
  • rowNumber 在源码中保留,但当前文档不推荐作为稳定公开能力使用。