Skip to content

Table 表格

表格组件,用于展示结构化数据。支持排序、自定义列、空状态、固定表头等常用功能。

何时使用:需要展示结构化数据(列表、报表)时使用。简单列表可考虑直接用 <table>

基础用法

最简单的表格,只需传入列配置和数据。

斑马纹与悬停

通过 stripedhoverable 属性增强表格可读性。

排序

在列配置中设置 sortable: true,即可点击表头进行排序。支持受控和非受控两种模式。

非受控模式(默认)

键盘操作

可排序表头不仅支持鼠标点击,还支持键盘操作

  • Tab 聚焦到可排序表头
  • EnterSpace 键触发排序
  • 排序状态通过 aria-sort 属性暴露给屏幕阅读器(ascending / descending

受控模式

通过 sort-keysort-order 控制排序状态,并监听 @sort 事件。

稳定行标识(row-key)

默认情况下,Table 使用行索引作为 DOM 的 key。当数据排序、过滤或更新时,行索引会变化, 导致 Vue 无法准确复用已有 DOM 节点,可能出现:

  • 单元格内容「跳动」或闪烁
  • 单元格内输入框 / 展开状态错位
  • 动画效果异常

通过 row-key 指定数据中的唯一字段(如 id),可让 Vue 始终正确匹配每一行。

💡 rowKey 指向的字段必须在每行数据中唯一(如数据库主键 id)。 若数据没有唯一字段,可跳过此 prop(默认按索引处理,简单场景够用)。 在受控排序:sort-key)或数据频繁更新时,设置 row-key 效果尤其明显。

固定表头

当表格数据较多时,可以固定表头,滚动时表头始终可见。

自定义字段名

如果数据字段不是预期的名称,可通过 labelKeyvalueKey 指定(与 Select 组件一致)。

自定义列内容

Table 组件提供两种自定义列内容的方式,你可以根据场景选择。

方式一:通用 cell 插槽(推荐)

使用 #cell 插槽统一处理所有列,通过 column.key 判断是哪一列。这种方式有完整的 IDE 自动补全提示。

方式二:精确列插槽 #column-{key}

为每一列单独定义插槽,插槽名称为 column- 加上列的 key 值。

两种方式对比

方式自动补全类型检查适用场景
#cell✅ 有提示✅ 有报错列较多,或需要 IDE 辅助
#column-{key}❌ 无提示✅ 有报错列较少,追求简洁

两种方式可以同时使用,精确列插槽优先级更高:

列宽与对齐

通过 widthalign 属性控制列样式。

空状态

数据为空时显示提示文案。可通过 empty-text 自定义文案,或通过 #empty 插槽完全自定义。

响应式

responsive 属性(默认开启)使表格在小屏幕下自动横向滚动,避免布局错乱。

行点击事件

通过 @row-click 监听行点击事件。

行选择

设置 selectable 属性显示选择列。选中行通过 v-model:selected-rows 双向绑定(数组),或通过 @selection-change 监听变化。

禁用指定行

通过 row-selectable 回调控制哪些行不可选(返回 false 禁用该行 checkbox):

行选择行为说明

  • 全选:表头 checkbox 一键全选/取消,自动跳过 row-selectable 禁用的行
  • 半选状态:部分行选中时表头 checkbox 显示 indeterminate 状态
  • 选中高亮:选中行添加 mg-table-row-selected 背景色
  • rowKey 配合(强烈建议):设置 row-key 后,排序/数据更新时选中状态按唯一标识比较,保持稳定;未设置时组件按对象引用识别行,若父组件重建 data 数组(重新赋值、过滤、排序、接口刷新),已选中的记录会因引用变化而"失联"

加载状态

Table 组件不内置加载状态,推荐配合 Skeleton 骨架屏组件使用:

API

Props

属性类型默认值说明
columnsTableColumn[][]列配置
dataany[][]表格数据
emptyTextstring'暂无数据'空状态文案(插槽优先)
showHeaderbooleantrue是否显示表头
stripedbooleanfalse是否显示斑马纹
hoverablebooleantrue是否显示悬停高亮
scrollablebooleanfalse是否强制横向滚动
responsivebooleantrue是否响应式(小屏自动滚动)
fixedHeaderbooleanfalse是否固定表头
maxHeightstring'400px'固定表头时的最大高度(配合 fixedHeader 使用)
sortKeystringundefined当前排序字段(受控模式)
sortOrder'asc' | 'desc'undefined当前排序方向(受控模式)
rowKeykeyof T | stringundefined行唯一标识字段名(稳定 key,排序/更新时避免 DOM 复用错乱)
selectablebooleanfalse是否显示选择列(行选择)
rowSelectable(row, index) => booleanundefined行是否可选(返回 false 禁用该行 checkbox)
selectAllTextstring'全选'全选 checkbox 的 aria-label
labelKeystring'label'全局默认标题字段名
valueKeystring'value'全局默认数据字段名

TableColumn 配置

属性类型说明
keystring数据字段名(与 valueKey 二选一,优先级更高)
titlestring列标题(与 labelKey 二选一,优先级更高)
widthstring列宽度(如 '100px''10%'
align'left' | 'center' | 'right'文本对齐方式
sortableboolean是否可排序
labelKeystring自定义标题字段名(当 title 未提供时使用)
valueKeystring自定义数据字段名(当 key 未提供时使用)

Slots

名称参数说明
cell{ row, column, value }通用单元格插槽,通过 column.key 判断列
column-{key}{ row, value }精确列插槽,key 为列的 keyvalueKey
empty自定义空状态内容

Events

事件参数说明
update:sortKey(key: string)排序字段变化(v-model:sort-key)
update:sortOrder(order: 'asc' | 'desc')排序方向变化(v-model:sort-order)
sort({ key, order })排序变化(合并事件)
row-click(row, index, event)点击行
update:selectedRows(rows: T[])选中行变化(v-model:selected-rows)
selection-change(rows: T[])选中行变化(与 update 同时触发)

类型支持

Table 组件使用 Vue 3.5+ 的泛型组件特性,自动从 data 推断行数据类型

vue
<script setup lang="ts">
// ✅ 不需要手动定义接口,自动推断
const users = ref([
  { id: 1, name: '张三', email: 'zhang@example.com' },
  { id: 2, name: '李四', email: 'li@example.com' },
])

// ✅ columns 配置时,key 自动提示只能是 id | name | email
const columns = [
  { key: 'name', title: '姓名' },
  { key: 'email', title: '邮箱' },
]

// ✅ 事件回调中 row 自动推断类型
const handleRowClick = (row, index) => {
  console.log(row.name)
}
</script>

<template>
  <Table :columns="columns" :data="users" @row-click="handleRowClick">
    <template #cell="{ row }">
      {{ row.name }}
    </template>
  </Table>
</template>

如需显式使用类型,可从包中导入:

typescript
import type { TableColumn, CellSlotProps } from 'moongate-vue'

注意事项

  • 排序支持数字和字符串类型,数字按数值比较,字符串按字典序比较
  • columns 中的 keyvalueKey 决定了插槽名称:#column-{key}#cell 中的 column.key
  • 空状态时,empty 插槽优先级高于 emptyText prop
  • responsive 默认开启,无需手动添加 overflow-x: auto
  • scrollableresponsive 可同时使用,效果为强制滚动
  • fixedHeader 需要配合 maxHeight 使用,否则表格会无限撑开
  • 固定表头时,表头会浮动在滚动内容上方,确保表格背景色已设置
  • 移动端建议谨慎使用固定表头功能
  • 建议在 tsconfig.json 中开启 strict: true 以获得最佳类型推断体验
  • 加载状态推荐配合 Skeleton 组件使用,Table 本身不内置加载逻辑
  • 行选择需设置 selectable,选中行通过 v-model:selected-rows 绑定数组
  • row-key 强烈建议配合行选择使用:设置后数据排序/更新时选中状态按唯一标识保持稳定;未设置时组件按对象引用识别行,父组件重建 data 数组(过滤/排序/接口刷新)会导致已选记录失效
  • 全选操作自动跳过 row-selectable 禁用的行

Released under the MIT License