Files
workspace/code/g3soft-libs/docs/content/ui/data/table.md
T
2026-10-12 17:32:50 +08:00

11 KiB
Raw Blame History

title, description
title description
Table 表格 高性能虚拟滚动表格,支持排序、固定列、多选、行内编辑、列宽 / 列序拖拽与行拖拽排序

Table 表格

Table 用于展示结构化数据,底层是 stk-table-vue,虚拟滚动 / 列宽拖拽 / 列序拖拽 / 区域选择 / 行拖拽排序都由它提供;组件负责性能门控、内部列管理与行内编辑态。

何时使用

  • 数据量大(成百上千行)且需要滚动流畅时;
  • 需要行内编辑、多选批量操作、列宽 / 列序可调时;
  • 数据量很小、只要一张静态表时,原生 <table> 或 Grid 更轻。

基础用法

给 columns 与 dataSource 两份数据即可。序号列(seq)默认开启,外框与圆角默认有(bordered)。

虚拟滚动与性能

组件内置两条门控,自动决定是否启用虚拟滚动,不需要业务手动切换:

方向 阈值 低于阈值时 原因
纵向 行数 > 100 全量渲染 库的虚拟滚动在「行数略多于单屏行数」时会把最后几行算出视口外,必须滚动才可见;行数少时全量渲染没有性能代价,却换来确定性正确的渲染
横向 列数 > 20 关掉横向虚拟 库在横向虚拟开启时会把每列宽度钉死为 minWidth ?? width ?? 100,未设 width 的列会失去「按比例铺满容器」的原生自适应

可以用 virtual / virtualX 关掉,但不能把它们强制打开到阈值以下。

除了门控,还有三处性能相关设计:

  • 无编辑行时不注入 customCell:纯展示列与非编辑态的可编辑列走库的原生 td 渲染路径,滚动时每格少一个函数式组件实例;
  • 尺寸变化 150ms 防抖:折叠动画 / 窗口缩放期间 ResizeObserver 每帧都会通知,逐帧重算会强制 reflow 并重渲染可见行列;组件合并到尺寸稳定后只刷新一次,并区分「仅宽度变化」只重算横向;
  • 选择列用原生 <input type="checkbox">:视觉由 CSS 模拟成 Checkbox 的外观,但每行不创建组件实例。

多选与批量操作

传 rowSelection 即在最前注入选择列;getCheckboxProps 可禁用个别行(禁用行不计入「全选」的分母)。

排序

列上写 sorter: true 即可点表头排序(组件内排序,不请求接口)。sortType 决定按数字还是字符串比较,默认字符串;需要自定义规则时 sorter 也可以传函数。

行内编辑

列上加 editor 即可编辑:单击单元格进入,Enter 确认、Esc 取消。

编辑器类型 说明
text / number / textarea 用 Input 渲染
select 用 Select 渲染;options 可以是数组,也可以是接收当前行的函数
checkbox 点击即切换,无需先激活整行;约定 1 = 选中、0 = 未选中(与后端 tinyint 对齐)

编辑器的输入值先写进内部草稿,失焦才落库并抛出 change。这样每敲一个字符不会触发父级重渲染(否则光标会丢、输入法会断)。用 editable={false} 可整体禁用编辑。

操作列

列上加 actions 渲染成一排小按钮;type: 'more' 的项会收进「更多」下拉。带 confirm 的操作先弹确认框,确认后才执行 onClick。

操作列建议显式写 resizable: false:它的宽度由内容决定,拖了不会落库,列一重建就丢。

列宽、列序与行拖拽

列宽 / 列序拖拽要求用 v-model:columns 绑定列定义——否则组件拖完无处回写(松手回弹),会直接关掉这两个功能。行拖拽排序用 row-draggable,顺序变化通过 row-order-change 回传。

API

Props

名称 类型 默认值 说明
columns G3TableColumn<T>[] [] 列定义,配合 v-model:columns 接收拖拽后的回写
dataSource T[] [] 数据源
rowKey string | (row) => string | number 'id' 行唯一键
virtual boolean true 纵向虚拟滚动总开关(实际是否开启受行数门控)
virtualX boolean true 横向虚拟滚动总开关(实际是否开启受列数门控)
rowHeight number 30 行高,同时驱动虚拟滚动计算
headerRowHeight number 34 表头行高
bordered boolean | string true 外框圆角描边 + 行分隔线;false 时只留行分隔线
colResizable boolean | object true 列宽拖拽;未绑定 v-model:columns 时自动关闭。可用 { disabled: (col) => boolean } 按列禁用
columnDraggable boolean | object true 列序拖拽;同上要求绑定 v-model:columns
rowDraggable boolean false 行拖拽排序
rowSelection TableRowSelection | null null 多选配置,见下
seq boolean | { title?, width? } true 序号列
activeRowKey string | number | null null 当前高亮行
editable boolean true 行内编辑总开关
noDataFull boolean true 空态铺满容器高度
showOverflow boolean true 内容溢出省略
autoFitWidth boolean false 非横向虚拟时铺满容器宽度(开启后关闭列宽拖拽)
theme 'light' | 'dark' — 不传则跟随全局主题(ConfigProvider / html[data-g3-theme])
footerData T[] [] 表尾数据
footerConfig object `` 表尾配置

列定义 G3TableColumn<T>

在 stk-table-vue 的列类型基础上扩展;下面只列自有字段,其余(width / minWidth / fixed / align / headerAlign / sorter / sortType / children / mergeCells 等)原样透传。

字段 类型 说明
dataIndex keyof T & string 取值字段
title string 表头文字
resizable boolean 该列是否可拖宽;操作列 / 展开列建议设 false
editor TableEditor<T> 行内编辑器,见下
actions TableAction<T>[] 操作列按钮
customCell (props) => VNode | string 自定义单元格渲染(逃生舱),传了就不再自动包装

editor

字段 类型 说明
type 'text' | 'number' | 'password' | 'textarea' | 'select' | 'checkbox' 编辑器类型
options TableSelectOption[] | ((row) => TableSelectOption[]) select 选项,可依赖当前行其它字段
disabled boolean | ((row) => boolean) 是否禁用该格编辑
allowClear boolean select 是否可清空,默认 true
emptyValue unknown select 清空后落库的值,默认 null
onChange (value, row, col) => void 本列值变化回调(早于组件的 change)

actions

字段 类型 说明
key string | number 唯一键;type: 'more' 的子项用它做下拉 key
label string 文案
type 'default' | 'danger' | 'delete' | 'more' 语义类型
icon Component 图标组件
visible boolean | ((row) => boolean) 是否显示
disabled boolean | ((row) => boolean) 是否禁用
confirm string | object 二次确认;字符串为标题,对象支持 title / description / okText / cancelText / okType / width / maskClosable
onClick (row) => void 点击回调(带 confirm 时在确认后执行)
items TableAction<T>[] type: 'more' 时的子项

Events

名称 参数 说明
update:columns (columns) 列宽 / 列序拖拽后回写(内部列已剥离)
update:selectedRowKeys (keys) 勾选变化
change (row, col, value) 行内编辑的值变化
row-order-change (rows, sourceIndex, targetIndex) 行拖拽排序完成
area-selection-change (ranges) 单元格选区变化(行内编辑依赖它)

Exposed

名称 类型 说明
scrollToRow(rowKey) Promise<void> 滚动到指定行
editRow(rowKey, focusCol?) Promise<void> 滚动到指定行并进入编辑
initVirtualScroll() / refreshLayout() — 手动重算虚拟滚动布局
getSelectedArea() / clearSelectedArea() — 读取 / 清空单元格选区
setRowExpand(...) — 展开 / 收起行(需配 expand 列)

Slots

名称 说明
empty 空态内容,默认显示「暂无数据」
expand 展开行内容(需列配置 type: 'expand')

实现说明

  • 底层是 stk-table-vue:虚拟滚动、列宽 / 列序拖拽、区域选择、行拖拽、二级表头、固定列、合并单元格都由它实现。组件不重复造这些轮子,只做门控与适配。
  • 库样式已并入 dist/style.css:库的 CSS 是独立文件(其 JS 里不含任何 .css import),组件 @use 了它,消费方不需要额外引一次第三方样式。
    • 注意 SCSS 里不能写 @use 'stk-table-vue/lib/style.css':带 .css 后缀时 Sass 不会内联,只原样输出一条 CSS @import 语句,产物里会留下一条浏览器解析不了的裸包路径。去掉后缀才会真正内联。
  • 主题通过覆盖库的 CSS 变量实现:库把 41 个主题值都做成了 .stk-table 作用域内的变量,组件把它们映射到 --g3-* 令牌(覆盖层在 src/table/style/_overrides.scss)。改变量而不是逐个选择器改样式,库升级时不容易失效。
  • 区域选择按需自注册:库的单元格区域选择是全局注册的(registerFeature(useAreaSelection)),不注册则 area-selection-change 永不触发、行内编辑失效。组件库不拥有 app 启动流程,因此首次挂载时自动注册一次;需要显式控制时可调用导出的 registerTableFeatures()。
  • data-testid 透传到内层:组件 inheritAttrs: false,$attrs 落在内层 StkTable 上。外框 / 圆角在我们自己的根节点 .g3-table 上,写 E2E 时按类名定位根节点。
  • 行编辑态存在 WeakMap 里:按行对象存,不给业务数据打标记;行被回收时状态自动释放。行与行之间切换编辑不翻转 editingActive,避免整表列重建。
  • RTL:布局用逻辑属性,带符号位移走 --g3-dir-sign;分隔条拖拽与键盘方向由库的 useDirection 处理。