@taocompany/magic-grid
Magic Grid
面向 Vue 3 的高性能虚拟表格组件库。采用命令式渲染 + 行 DOM 池 + 双轴虚拟化,可稳定承载百万级行数据;API 设计对标 AG Grid 社区版,覆盖排序、筛选、编辑、行分组、树形表格、框选、剪贴板等完整表格能力。
目录
- 概述
- 架构与设计
- 快速开始
- 行移动
- 数据与性能最佳实践
- 树形表格
- 默认配置
- Props
- Options 类型参考
- 筛选模型参考
- Events
- Expose
- Slots
- 单元格编辑
- 数据校验
- 键盘导航与快捷键
- 辅助组件
- 包入口与导出
- TypeScript 集成
- 类型与校验子路径
概述
特性
| 类别 | 能力 |
|---|---|
| 性能 | 行/列双轴虚拟化、DOM 池复用、RAF 帧预算分片、Cell Renderer 滚动调度(idle flush · 按行合并 · placeholder-then-vue)、增量数据管线 |
| 数据 | 排序、列筛选、Quick Filter、事务增量更新(applyTransaction)、行 CRUD、行移动(moveRow / moveRows) |
| 交互 | 单元格/行编辑(内置 text/number/checkbox/switch · overlay/inline)、校验、行选择、索引列定位、框选与剪贴板 |
| 布局 | 固定列、列拖拽/调整宽度、列有效性与显隐(available / hidden)、合并单元格、动态行高、主从展开行 |
| 结构 | 行分组、树形表格(含懒加载)、表尾汇总 |
| 体验 | 溢出 Tooltip、单元格批注、空态 Overlay、暗色主题、底部状态栏 |
| 扩展 | 列设置面板、内置编辑器(text/number/checkbox/switch)、Vue 第三方编辑器 Composable、inline 常驻编辑器、async-validator 校验 |
当前版本:0.7.5(@taocompany/magic-grid)。
上手路径:安装 → 快速开始 → 按需查阅 行移动、树形表格 等专题,以及下文 Props / Events / GridApi 索引。
环境要求
- Node.js >= 20.19
- Vue ^3.5.0
- async-validator ^4.2.0(校验功能 peer dependency)
安装
pnpm add @taocompany/magic-grid async-validator
引入样式
样式不会随 JS 自动注入。须先 token、后 style(全局引入一次):
import '@taocompany/magic-grid/tokens.css'
import '@taocompany/magic-grid/style.css'
ColumnSettingsButton / ColumnSettingsPanel 与 MagicGrid 共用上述两份 CSS。按钮若在 MagicGrid 容器外,同样必须引入;列设置相关 token 在
.mg-column-settings-button/.mg-column-settings-portal上也会注入,脱离.magic-grid可正常显示。主题拆分见 docs/48-theme-tokens-style-split.md;平台自定义 token 与可视化导出方案见 docs/49-theme-studio.md(在tokens.css之后加载mg-theme-overrides.css)。
架构与设计
Magic Grid 采用 命令式渲染内核 + Vue 薄封装 的分层架构,对标 AG Grid 社区版 API 语义,渲染路径针对百万级行数据做了专门优化。
分层结构
| 层级 | 职责 | 关键模块 |
|---|---|---|
| Vue 层 | Props / Events / Slots 绑定、主题 CSS 变量、辅助 UI | MagicGrid.vue、ColumnSettings、StatusBar |
| Grid API | 命令式数据、列、编辑、选择、框选 | GridApi |
| 渲染引擎 | 双轴虚拟化、行 DOM 池、增量 cell 刷新 | rowRenderer、rowPool |
| 数据管线 | 排序 / 筛选 / 分组 / 树形 / 映射 | pipeline stages |
| 交互层 | 焦点、框选、编辑、拖拽、剪贴板、批注 | gridInteraction |
渲染模型
- 行虚拟化:仅渲染视口 +
rowBuffer缓冲行;行 DOM 在行池内按rowKey复用,滚动时更新内容与位置。 - 列布局:左固定 / 中心 / 右固定三 lane;中心 lane 随横滚分配列宽。
- 增量更新:
applyTransaction、setData走 RowNode 增量管线;beginUpdate/endUpdate可合并多次刷新。 - 帧预算:大批量 DOM 写入分片到
requestAnimationFrame(默认 60ms/帧);cellRenderer/#cell-xxx插槽走 f1 低优先级队列,可通过 Cell Renderer 滚动渲染 调优;测试场景可调用flushFrames()同步 flush。
数据管线顺序
| 模式 | Stage 顺序 |
|---|---|
| 扁平表格 | sort → filter → map |
| 行分组 | group → filter → sort → aggregate → map |
| 树形表格 | tree → filter → sort → map |
详见 树形表格 专章。
summaryScope: 'displayed'、状态栏行数、框选聚合均基于 rowsToDisplay;summaryScope: 'all' 对 sourceRows 全量汇总(忽略 filter)。
快速开始
<script setup lang="ts">
import { ref } from 'vue'
import { MagicGrid } from '@taocompany/magic-grid'
import type { ColumnDef, MagicGridExpose, RowData } from '@taocompany/magic-grid/types/core'
import '@taocompany/magic-grid/tokens.css'
import '@taocompany/magic-grid/style.css'
const gridRef = ref<MagicGridExpose>()
const columns: ColumnDef[] = [
{ prop: 'name', label: '姓名', width: 120 },
{ prop: 'age', label: '年龄', width: 80 },
{ prop: 'city', label: '城市', flex: 1 },
]
const data: RowData[] = [
{ id: 1, name: '张三', age: 28, city: '上海' },
{ id: 2, name: '李四', age: 32, city: '北京' },
]
function onSelectionChanged(event: { selectedRowIds: readonly (string | number)[] }) {
console.log('选中行:', event.selectedRowIds)
}
</script>
<template>
<MagicGrid
ref="gridRef"
:columns="columns"
:data="data"
row-key="id"
height="400"
row-selection="multiple"
sortable
filterable
stripe
@selection-changed="onSelectionChanged"
/>
</template>
提示:
data应为普通对象数组,避免对行数据使用reactive()深代理。
上例通过 Grid 级 sortable / filterable 开启全列默认可排序、可筛选;个别列可用 sortable: false / filterable: false 关闭。详见 Grid 级默认与列级覆盖。
替代写法(逐列显式配置):
const columns: ColumnDef[] = [
{ prop: 'name', label: '姓名', width: 120, sortable: true },
{ prop: 'age', label: '年龄', width: 80, sortable: true },
{ prop: 'city', label: '城市', flex: 1, filterable: true },
]
<MagicGrid :columns="columns" :data="data" row-key="id" height="400" />
行移动
MagicGrid 支持编程式 API与索引列 UI 拖拽两种方式调整行序。无论哪种方式,最终都修改 source 数组(即 api.getData() / ref.getData() 返回的顺序),表格按当前 sort / filter / 分组 / 树形规则重新计算可见顺序(rowsToDisplay)。
核心概念:source 与 display
| 概念 | 含义 | 消费端如何观察 |
|---|---|---|
| source 顺序 | 业务数据在内存中的存储顺序 | getData() 下标 · RowNode.sourceIndex · snapshot.sourceIndex · getRowIndex(id) 默认 |
| display 顺序 | sort/filter/分组后屏幕可见顺序 | RowNode.rowIndex · snapshot.rowIndex · getRowIndex(id, { type: 'display' }) |
| rowsToDisplay | 内核可见行列表(含 groupHeader 等) | 不直接暴露;分组表 indexMode:'display' 的 toIndex 含 header/footer |
分组表 source 序:开启 rowGrouping 后,setData / 事务 / 分组键配置变更触发的全量 refresh 前,source 会按分组键 collation 归一化(组间 groupComparator,组内稳定相对顺序)。因此稳态下 getData() 已是「组块 + 组内序」,不是长期交错的 raw 数组。展开/折叠(map-only refresh)不会重排 source。
组内换序只改变 source 中同组 leaf 的相对位置,不会把行移到另一组(跨组须改分组字段值)。
行移动前置配置
| Prop | 典型值 | 说明 |
|---|---|---|
show-index-column |
true |
显示索引列;drag handle 与 index focus 的前提 |
index-column.showRowDragHandle |
true |
索引列左侧拖拽把柄 |
index-column.focusMode |
'multiple' |
索引列多选 focus,可整块移动(不读取 checkbox 行选) |
row-drag-managed |
true(默认) |
drop 后自动写回 source 并触发 row-moved;false 时自行监听 row-drag-end 改序 |
<MagicGrid
show-index-column
:index-column="{ showRowDragHandle: true, focusMode: 'multiple' }"
row-drag-managed
@row-moved="onRowMoved"
/>
平铺表:UI 拖拽与 API
UI 拖拽:在索引列 focus 一行或多行 → 拖左侧 handle → 松手后 source 顺序更新。
编程式 API:
const api = gridRef.value?.api
// 移动单行:将 id=3 的行移到 source 下标 0
api?.moveRow(3, 0)
// 批量移动:将 id 2、3、4 作为一块移到 source 下标 0,块内相对顺序不变
api?.moveRows({ rowIds: [2, 3, 4], toIndex: 0 })
// 结合索引列 focus(默认 mode: 'all',含临时行 internalRowId)
const rowIds = api?.getIndexFocusedRowIds() ?? []
if (rowIds.length > 0) {
api.moveRows({ rowIds, toIndex: 0, indexMode: 'display' })
}
moveRows 不读取 checkbox 选区(rowSelection)。若需按 checkbox 选中移动,请 generateSelectedRowIds(getSelectedRows())。
勿将 indexFocusChanged 的 focusedRowIds(临时行为 null)直接传给 moveRows;请用 getIndexFocusedRowIds() 或 generateFocusedRowIds(focusedRows)。
返回值 RowMoveResult:{ moved: true, fromIndex, toIndex, moves? } 或 { moved: false, reason }。失败时 不修改 source,不 emit row-moved。
步进换序 moveUp / moveDown
一行代码在相邻行之间步进换序,返回移动后的 RowSnapshot;边界或行不存在时 null。
| 表形态 | 步进范围 | 内部坐标 |
|---|---|---|
| 平铺表 | 全局 source 邻居 | indexMode: 'source' |
| 分组表 | 同 leafGroupPathKey 组内 leaf |
indexMode: 'source'(collation 后的 source 子序列) |
| 树形表 | 同父兄弟 | indexMode: 'display'(可见兄弟邻居) |
import { generateRowId } from '@taocompany/magic-grid'
const row = api.getIndexFocusedRows()[0]
if (!row) return
const snapshot = api.moveUp(generateRowId(row)) // 上移一位
// api.moveDown(generateRowId(row)) // 下移一位
// snapshot?.sourceIndex · snapshot?.rowIndex // 移动后的下标
Playground:/docs/row-move-step(平铺)· /docs/row-move-step-grouped(分组)。
分组表:组内换序
开启 rowGrouping 后,行移动**限定在同一分组下的数据行(leaf)**内,不可跨组、不能通过 drag/API 改分组字段。
<MagicGrid
row-grouping
show-group-header
show-index-column
:index-column="{ showRowDragHandle: true, focusMode: 'multiple' }"
row-drag-managed
:columns="[
{ prop: 'department', rowGroup: true, rowGroupIndex: 0, label: '部门', width: 120 },
{ prop: 'name', label: '姓名', width: 120 },
]"
/>
推荐:组内步进用上一节的 moveUp / moveDown(无需手算邻居下标)。
高级:moveRow / moveRows + indexMode: 'display'(与 UI drag 同语义):
const rowIds = api.getIndexFocusedRowIds()
if (rowIds.length === 0) return
const rowId = rowIds[0]!
const department = api.getData().find((r) => String(r.id) === String(rowId))?.department
const groupLeaves = api.getData().filter((r) => r.department === department)
const pos = groupLeaves.findIndex((r) => String(r.id) === String(rowId))
const neighbor = groupLeaves[pos - 1] // 上移时
if (!neighbor) return
const toIndex = api.getRowIndex(neighbor.id, { type: 'display' })
if (toIndex == null) return
api.moveRow(rowId, toIndex, 'display')
跨组时返回 { moved: false, reason: 'cannot move rows across groups' }。
完整示例:Playground /docs/row-move-grouped。
indexMode 说明
| 值 | toIndex 含义 |
适用场景 |
|---|---|---|
'source'(默认) |
source 数组下标(分组表 = collation 归一化后的序) | 平铺表、分组表组内换序 |
'display' |
当前可见行下标(含 groupHeader 等) | 按肉眼可见顺序移动;分组表 moveRow 高级用法 |
sort 或 filter 激活时:moveRow / moveRows / moveUp / moveDown 与 managed 拖拽 handle 全部不可用;须先 clearAllFilters() / setSortModel([])。
约束与常见失败原因
| 场景 | 行为 |
|---|---|
| sort 或 filter 激活 | managed 拖拽 handle 隐藏;moveRow / moveRows / moveUp / moveDown 全部拒绝 |
| 行分组 | 须同一组 leaf;不可跨组 |
| 树形 | 须同一父节点下兄弟;跨父 reorder 仅 UI hierarchy drag + asyncRowMutation.move |
常见 reason:row move is not allowed while sort or filter is active · no rows to move · selected rows must belong to the same group · cannot move rows across groups · selected rows must belong to the same tree parent
事件
| 事件 | 说明 |
|---|---|
@row-moved / api.on('rowMoved') |
换序成功后触发;source: 'api' 或 'uiRowDrag';fromIndex / toIndex 为 source 下标 |
@row-drag-end |
rowDragManaged: false 时由业务自行改序 |
@index-focus-changed |
索引列 focus 变化(与 checkbox 选区独立) |
moveRows 参数与返回值
MoveRowsGridApiOptions:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
rowIds |
RowId[] |
— | 必填。待移动行的业务 rowKey(string | number) |
toIndex |
number |
— | 必填。目标下标;含义由 indexMode 决定 |
indexMode |
'source' | 'display' |
'source' |
下标基准 |
leaderRowId |
RowId |
source 中最早出现的行 | 块 anchor:toIndex 表示 leader 移动后的位置,其余行随块保持相对顺序 |
RowMoveResult:
| 字段 | 类型 | 说明 |
|---|---|---|
moved |
boolean |
是否发生位移 |
fromIndex |
number? |
leader 变更前 source 下标 |
toIndex |
number? |
leader 变更后 source 下标 |
moves |
{ rowId, fromIndex, toIndex }[]? |
块内各行位移明细 |
reason |
string? |
moved: false 时的失败原因 |
moveRow(rowId, toIndex, indexMode?) 为单行语法糖;moveRows 在 rowIds.length === 1 时与之等价。更多 API 索引见 GridApi、事件见 row-moved。
数据与性能最佳实践
行数据
data使用普通对象数组,不要对行数据做reactive()深代理;Grid 内部维护 RowNode,深代理会显著拖慢增量更新。rowKey必须稳定唯一(业务主键);临时新增行可省略主键,内核分配__MG_TMP__::*(不对用户暴露),落库后调用promoteRowId。- 大批量写入优先
applyTransaction或beginUpdate/endUpdate包裹多次 API 调用,避免连续setData全量替换。
列定义
- 动态列用
columnsprop 热更新即可;available: false从模型裁剪,hidden: true保留模型仅不渲染。 - flex 列与固定
width列混用时,剩余空间由 flex 权重分配;sizeColumnsToFit/autoSizeStrategy可首屏自适应。 - 需要权限裁剪时用
available,需要用户临时隐藏列时用hidden+ 列设置面板。
性能提示
- 避免在
cellRenderer/formatter/valueGetter中创建重量级对象或触发外部副作用;这些函数在滚动时会高频调用。 - 多列使用
#cell-{colId}Vue 插槽时,滚停后可能出现 renderer 列空白拖尾;见下方 Cell Renderer 滚动渲染。 - 合并单元格(
enableCellSpan)会启用style.top行定位并增加 span cache 开销,仅在确有需求时开启。 - 生产环境可通过
@scroll(ScrollEvent)监听滚动位置,通过@data-rendered(GridMetrics)订阅渲染完成时机;开发调试时可关注 DOM 行池规模与setData耗时。
Cell Renderer 滚动渲染
带 cellRenderer 或 #cell-{colId} 插槽的列在滚动时走 f1 异步队列(与 prop / formatter 列的同步 textContent 路径不同)。多 Vue 组件列场景下,可通过以下 Grid 级 prop 调优(默认均保持优化前行为,需显式开启):
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
scrollEndFlushMs |
number |
0 |
滚动停止 debounce 后 flush RAF;多 Vue 列建议 100~200 |
frameBudgetMs |
number |
60 |
活跃滚动时每帧任务预算(ms) |
scrollEndFrameBudgetMs |
number |
-1 |
idle flush 帧预算;-1 = 一次跑完 |
cellRendererDefer |
'always' | 'never' | 'sync-only' |
'always' |
renderer 是否进入 f1;sync-only 仅 Vue renderer 异步 |
deferRowDestroyOnScroll |
boolean |
false |
滚动 active 期间延迟行 destroy + Vue unmount |
rendererFrameBudgetMs |
number |
20 |
滚动 active 时为 f1 预留的每帧保底预算(ms);0 = 与 p1/p2 共享 |
cellRendererPresentation |
'immediate' | 'deferred' | 'placeholder-then-vue' |
'deferred' |
placeholder-then-vue:滚动态先显示 formattedValue,idle 后 mount Vue |
rowBuffer |
number |
10 |
行虚拟化缓冲;多 Vue 列可降至 3~5 |
列级可选 cellRendererMount: 'vue' | 'sync',配合 cellRendererDefer: 'sync-only' 精确控制哪些列走 f1。
多 slot 列业务表推荐配置(如 ProductOrder):
<MagicGrid
:row-buffer="5"
:scroll-end-flush-ms="150"
:renderer-frame-budget-ms="20"
:defer-row-destroy-on-scroll="true"
cell-renderer-presentation="placeholder-then-vue"
cell-renderer-defer="always"
...
/>
placeholder-then-vue 模式下,slot 列需配置可读 prop 或 formatter,滚动态才有文字兜底。调优项见上表。
树形表格
树形表格(Tree Table)在 扁平 data 数组 上,通过 getDataPath 为每行提供 从根到当前节点的路径(string[]),内核据此构建层级并 DFS 投影 为可见的 rowsToDisplay。对标 AG Grid Tree Data 社区版语义。
与行分组互斥:
tree: true与rowGrouping: true不得同时生效。双开时控制台 dev 警告,tree优先,rowGrouping及ColumnDef.rowGroup被忽略。flat / group / tree 三选一,见 概述与核心概念。
概述与核心概念
为什么用扁平数组 + getDataPath?
Magic Grid 不支持嵌套 children 字段作为树数据源(与 AG Grid CSRM 一致)。所有行仍存放在 同一个 data 数组 中;层级关系完全由 getDataPath({ data }) => string[] 表达:
| 概念 | 说明 |
|---|---|
dataPath |
从根到当前节点的路径段,如 ['总部', '研发部', '前端组'] |
treeLevel |
深度,根节点 = 0,等于 dataPath.length - 1 |
parentRowId |
父节点 rowKey;根节点为 undefined |
rowsToDisplay |
折叠感知的 DFS 扁平投影;渲染层 只消费此数组 |
sourceRows |
业务 flat 数组;getData() / applyTransaction 仍操作此层 |
示例路径(组织树):
| 行 id | dataPath | treeLevel | 含义 |
|---|---|---|---|
hq |
['HQ'] |
0 | 根 |
eng |
['HQ', '研发'] |
1 | HQ 下研发部 |
fe |
['HQ', '研发', '前端'] |
2 | 研发部下前端组 |
路径规则(必须遵守)
- 前缀唯一确定父子:
['A','B']的父路径必须是['A'];缺父路径 → 建树 throw。 - 同一路径不得对应多行:重复路径 → 建树 throw。
- 路径段为任意字符串:可含中文、空格、特殊字符;内核用
\0拼接做内部 key。 rowKey必须稳定唯一:与 flat 表格相同;临时行内部 id 为__MG_TMP__::*,落库后promoteRowId。
数据管线(tree 模式)
启用 tree: true 后,阶段顺序为:
sourceRows(flat)
→ [tree] TreeBuildStage(getDataPath 建树)
→ [filter] 递归过滤 · 空枝剪枝
→ [sort] 同级兄弟排序(不跨层)
→ [map] DFS 扁平化(折叠跳过子树)
→ [afterMap] detail 行注入(若 masterDetail)
→ positionRows → displayRows
- expand/collapse 走 map-only 快路径(
refreshModel({ stages: ['map'] })),不重跑 tree/filter/sort。 summaryScope: 'displayed'、状态栏行数、框选聚合均基于投影后的可见行。
与 rowGrouping 的区别
| 维度 | 行分组 (rowGrouping) |
树形表格 (tree) |
|---|---|---|
| 层级来源 | 列值 rowGroup 聚合 |
getDataPath 路径 |
| 数据行 | leaf + synthetic group 行 | 全部为 user data 行 |
| 系统列 | auto group 列(__group__) |
tree 列(__tree__) |
| 管线 | group → filter → sort → aggregate → map |
tree → filter → sort → map |
| 互斥 | 与 tree 不得双开 |
与 rowGrouping 不得双开 |
树形表格快速上手
<script setup lang="ts">
import { ref } from 'vue'
import { MagicGrid } from '@taocompany/magic-grid'
import type { ColumnDef, GetDataPathFn, RowData } from '@taocompany/magic-grid/types/core'
import '@taocompany/magic-grid/tokens.css'
import '@taocompany/magic-grid/style.css'
interface OrgRow extends RowData {
id: string
org: string
dept?: string
team?: string
name: string
headcount: number
}
/** flat 源数据——无 children 嵌套 */
const data = ref<OrgRow[]>([
{ id: 'hq', org: 'HQ', name: '总部', headcount: 120 },
{ id: 'eng', org: 'HQ', dept: '研发', name: '研发部', headcount: 80 },
{ id: 'fe', org: 'HQ', dept: '研发', team: '前端', name: '前端组', headcount: 20 },
{ id: 'be', org: 'HQ', dept: '研发', team: '后端', name: '后端组', headcount: 25 },
{ id: 'sales', org: 'HQ', dept: '销售', name: '销售部', headcount: 30 },
])
const columns: ColumnDef[] = [
{ prop: 'name', label: '名称', width: 140, filterable: true },
{ prop: 'headcount', label: '人数', width: 88, sortable: true },
]
/** 由 org → dept → team 拼路径;也可直接读 row.pathSegments */
const getDataPath: GetDataPathFn = ({ data }) =>
[data.org, data.dept, data.team].filter(Boolean).map(String)
</script>
<template>
<MagicGrid
:data="data"
:columns="columns"
row-key="id"
height="480"
tree
:get-data-path="getDataPath"
:group-default-expanded="-1"
:row-selection="{ mode: 'multiple', groupSelectsChildren: true }"
@tree-node-opened="(e) => console.log('treeNodeOpened', e)"
/>
</template>
效果:左侧自动注入 tree 系统列(缩进 + chevron + 路径末段或 name),支持折叠/展开、同级排序筛选、父子联动行选。
树形表格配置项详解
以下为树形相关 Grid 级 prop 完整说明。类型定义见 @taocompany/magic-grid/types/core 中的 TreeTableGridOptions。
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
tree |
boolean |
false |
总闸。true 时启用树形模式;必填 getDataPath |
getDataPath |
GetDataPathFn |
— | ( { data } ) => string[],每行返回路径。tree: true 时必填,缺失则 throw |
groupDefaultExpanded |
number |
-1 |
默认展开层级(tree / group 共用此 prop)。0 = 全折叠;1 = 仅展开第一层;-1 = 全部展开 |
showTreeColumn |
boolean |
true |
是否注入 tree 系统列(colId __tree__) |
autoTreeColumnDef |
Partial<ColumnDef> |
— | 覆盖 tree 列宽、pinned、headerName 等;对标 AG Grid autoGroupColumnDef |
treeValueGetter |
TreeValueGetterFn |
— | 自定义 tree 列展示文案;缺省为 dataPath 末段 |
treeDisplayType |
'singleColumn' |
'singleColumn' |
v1 仅单列树展示 |
treeLazyLoad |
boolean |
false |
启用 CSRM 懒加载;true 时需 loadTreeChildren |
hasTreeChildren |
HasTreeChildrenFn |
— | lazy:true 时即使 source 尚无子孙也展示 expand chevron |
loadTreeChildren |
LoadTreeChildrenFn |
— | lazy:首次展开且无已加载子行时异步拉取子数据 |
treeDragScope |
'siblings' | 'hierarchy' |
'siblings' |
行拖拽范围,见 行拖拽与层级变更 |
setDataPath |
SetDataPathFn |
— | hierarchy 模式下 drag/shortcut 写回路径到 row.data |
treeHierarchyActions |
boolean |
true |
hierarchy + setDataPath 时,tree 列 hover 展示 上移一级 / 下移一级 菜单 |
回调类型签名:
type GetDataPathFn = (params: { data: RowData }) => string[]
interface TreeValueGetterParams {
data: RowData
dataPath: string[]
treeLevel: number
}
type TreeValueGetterFn = (params: TreeValueGetterParams) => string
interface HasTreeChildrenParams {
data: RowData
dataPath: string[]
treeLevel: number
}
type HasTreeChildrenFn = (params: HasTreeChildrenParams) => boolean
interface LoadTreeChildrenParams {
parentRowId: BusinessRowId
parentData: RowData
dataPath: string[]
treeLevel: number
signal: AbortSignal // 折叠 / destroy 时可 abort
}
type LoadTreeChildrenFn = (
params: LoadTreeChildrenParams,
) => Promise<RowData[] | void> | RowData[] | void
interface SetDataPathParams {
data: RowData
dataPath: string[]
treeLevel: number
previousPath: readonly string[]
}
type SetDataPathFn = (params: SetDataPathParams) => void
setDataPath默认行为:未传入时,若data.pathSegments为数组,内核会自动data.pathSegments = [...dataPath]。业务字段(如org/dept)需自行在setDataPath中同步。
数据模型与 getDataPath
推荐建模方式
方式 A — 路径存于业务字段(推荐,便于持久化):
interface MenuRow {
id: number
pathSegments: string[] // ['系统管理', '用户管理', '角色列表']
title: string
}
const getDataPath: GetDataPathFn = ({ data }) => data.pathSegments
方式 B — 路径由字段拼接(适合固定层级列):
const getDataPath: GetDataPathFn = ({ data }) =>
[data.org, data.dept, data.team].filter(Boolean).map(String)
方式 C — hierarchy 拖拽后写回(需 setDataPath):
const setDataPath: SetDataPathFn = ({ data, dataPath }) => {
data.pathSegments = [...dataPath]
data.org = dataPath[0]
data.dept = dataPath[1]
data.team = dataPath[2]
}
Transaction 与增量更新
树形模式下 applyTransaction 仍操作 flat sourceRows:
// 新增子节点(路径必须含正确父前缀)
api.applyTransaction({
add: [{ id: 'new-fe', org: 'HQ', dept: '研发', team: '前端', name: '新小组', headcount: 5 }],
})
// 删除节点不会自动删子孙——需自行收集子树 id 后 remove
api.applyTransaction({ remove: ['fe', 'be'] })
懒加载成功时,内核 内部等价于 applyTransaction({ add: children }) 并 refresh tree 阶段。
getDataPath 与 getData() 的关系
api.getData()返回 flat sourceRows(与 AG Grid 一致),不是 DFS 投影顺序。api.getDataPath(rowId)查询某行的当前路径。- 展示顺序以
rowsToDisplay为准;行索引列对 display 行 连续编号(1…N)。
树列 UI 与系统列
系统列顺序
启用 tree 后,列注入顺序为:
index(可选) → selection(可选) → expand(masterDetail 可选) → tree(__tree__) → 用户列
- tree 列默认 左固定(
pinned: 'left'),默认宽 200px,最小 120px。 - 用户
columns中 不得占用保留 colId:__tree__、__index__、__selection__、__expand__、__group__(冲突时 dev 警告并忽略)。
展示内容
| 元素 | 说明 |
|---|---|
| 缩进 | 每级 16px(padding-left = treeLevel × 16) |
| Chevron | 可展开节点显示;叶节点隐藏或占位对齐 |
| 文案 | 默认 dataPath 末段;可用 treeValueGetter 覆盖 |
| Loading | lazy 加载中 chevron 区 spinner + aria-busy |
| Settings 菜单 | treeDragScope: 'hierarchy' 且 setDataPath 可用时,hover 显示 settings 按钮 |
自定义 tree 列
<MagicGrid
tree
:get-data-path="getDataPath"
:auto-tree-column-def="{
headerName: '组织结构',
width: 240,
pinned: 'left',
}"
:tree-value-getter="({ data, dataPath }) => `${dataPath.join(' / ')} · ${data.name}`"
/>
隐藏 tree 列(仅保留层级逻辑、自行在业务列渲染缩进):
<MagicGrid tree :get-data-path="getDataPath" :show-tree-column="false" />
键盘与无障碍
- 焦点在 tree cell 时:Enter / Space 切换展开/折叠。
- Chevron 带
aria-expanded;lazy loading 时aria-busy="true"。
展开与折叠
用户交互
- 点击 tree 列 chevron 切换当前节点展开/折叠。
- 点击 tree 列头 chevron(与行内同款图标):全部展开 / 全部收起;当所有可展开节点均已展开时 chevron 旋转为展开态,再次点击则
collapseAll()。 - 折叠父节点时,子孙不出现在
rowsToDisplay(非display: none,而是从投影中移除,不参与虚拟化行计数)。
Grid API
| 方法 | 说明 |
|---|---|
expandNode(rowId) |
展开节点;lazy 模式下若子行未加载会先 await loadTreeChildren |
collapseNode(rowId) |
折叠节点;会 abort 该节点在途 lazy 请求 |
isNodeExpanded(rowId) |
查询展开态 |
expandAll() |
展开 已加载 子树;不会递归触发 lazy load(避免请求风暴) |
collapseAll() |
折叠全部 |
getDataPath(rowId) |
返回 string[] 或 undefined |
const api = gridRef.value?.api
api?.expandNode('eng')
api?.collapseNode('hq')
console.log(api?.isNodeExpanded('eng')) // false
console.log(api?.getDataPath('fe')) // ['HQ', '研发', '前端']
事件 tree-node-opened
| 字段 | 类型 | 说明 |
|---|---|---|
rowId |
BusinessRowId |
节点 id |
expanded |
boolean |
true 展开 / false 折叠 |
level |
number |
treeLevel |
dataPath |
string[] |
节点路径 |
source |
'api' | 'ui' |
API 调用或用户点击 chevron |
树形懒加载
适用于 初始仅加载根节点、按需展开拉取子级的场景。仍为 CSRM(客户端行模型),不是 SSRM 服务端分页树。
启用条件
<MagicGrid
tree
tree-lazy-load
:get-data-path="getDataPath"
:has-tree-children="({ data }) => Boolean(data.hasChildren)"
:load-tree-children="loadChildren"
@tree-children-loading="onLoading"
@tree-children-loaded="onLoaded"
@tree-children-load-failed="onFailed"
/>
| 配置 | 必填 | 说明 |
|---|---|---|
treeLazyLoad: true |
是 | 总闸 |
loadTreeChildren |
是 | 未提供时 dev 警告,行为退化为 M24 全量 tree |
hasTreeChildren |
强烈建议 | 控制 尚未加载 时是否显示 chevron |
getDataPath |
是 | 与全量 tree 相同 |
首次展开时序
用户点击 chevron / expandNode API
→ 若 loadedParentIds 已有 → 直接 map 展开
→ 若 inflight 已有 → 复用同一 Promise
→ emit treeChildrenLoading
→ await loadTreeChildren({ parentRowId, parentData, dataPath, treeLevel, signal })
→ 成功:校验路径 / rowKey 唯一 → applyTransaction({ add }) → refresh tree 阶段
→ emit treeChildrenLoaded → 子孙可见
→ 失败:emit treeChildrenLoadFailed · source 不变 · 保持折叠
→ Abort(折叠/destroy):丢弃 late resolve · 不污染 source
loadTreeChildren 实现要点
async function loadChildren({
parentRowId,
parentData,
dataPath,
signal,
}: LoadTreeChildrenParams): Promise<RowData[]> {
const res = await fetch(`/api/org/${parentRowId}/children`, { signal })
if (!res.ok) throw new Error('load failed')
const rows = await res.json()
// 每行必须能被 getDataPath 解析,且路径前缀包含 parent 的 dataPath
return rows
}
| 规则 | 说明 |
|---|---|
| 幂等 | 同一 parentRowId 成功加载后 不重复请求 |
| 空子树 | 返回 [] → 标记为已加载叶节点 · chevron 消失 |
| 路径校验 | 子行 getDataPath 必须以父路径为前缀;否则 loadFailed |
| AbortSignal | 须在 signal.aborted 时停止;折叠父节点会 abort |
| expandAll | 不批量触发 lazy load |
懒加载事件
| 事件 | 关键字段 |
|---|---|
tree-children-loading |
parentRowId, dataPath, treeLevel, source |
tree-children-loaded |
parentRowId, children, childCount, source |
tree-children-load-failed |
parentRowId, reason?, aborted? |
排序、筛选与汇总
| 操作 | 树形语义 |
|---|---|
| 列排序 | 仅在 同一 parentRowId 下兄弟 间重排;不改变 dataPath |
| 列筛选 / Quick Filter | 递归匹配 data 行;某父下子孙全被滤掉 → 父节点隐藏(空枝剪枝) |
| 表尾汇总 | summaryScope: 'displayed' 时仅聚合 可见 data 行(含各层父节点) |
| lazy 未加载分支 | 不参与 filter/sort/drag(RowNode 尚不存在) |
行选择与 groupSelectsChildren
树形模式下行选择配置与 flat 相同,通过 row-selection prop:
<MagicGrid
:row-selection="{ mode: 'multiple', groupSelectsChildren: true }"
/>
groupSelectsChildren |
行为 |
|---|---|
true(默认) |
选中父 → 递归选中 display 中可见 子孙;取消父 → 递归取消 |
false |
父子 checkbox 独立;子全选时父 indeterminate;父选中 不自动选子 |
注意:
- 折叠的子孙不参与级联(未投影到 display 的行不在选区内)。
- lazy 加载完成前,父选中 不会 预选尚未加载的子孙。
- 所有 data 行(含非叶节点)均可被选中、编辑。
行拖拽与层级变更
树形行拖拽需开启 indexColumn.showRowDragHandle: true(或列级 drag handle)。与 rowDragManaged 配合使用;配置 asyncRowMutation.move 时拖拽自动 await 持久化。
treeDragScope: 'siblings'(默认)
- drop 仅限同一
parentRowId下兄弟 间换序。 - 跨父 drag → 禁止光标 · 不 emit
rowMoved。 - 不改变
dataPath;仅调整 source 平铺顺序中的兄弟区间。
treeDragScope: 'hierarchy'
允许 跨层级改挂(改父节点),必须提供 setDataPath 写回路径:
| 操作 | 如何触发 |
|---|---|
| 挂到目标行下(nest) | 拖到 tree 列 子级缩进热区(目标行右侧),或 按住 Alt 再 drop |
| 同级换序 / 改父到根或旁支 | 拖到目标行 同级区域(默认 drop 区) |
| 上移一级 / 下移一级 | tree 列 hover settings-2 菜单(需 treeHierarchyActions !== false) |
层级快捷菜单语义:
| 菜单项 | 行为 |
|---|---|
| 上移一级 | 有父节点 → outdent 到父的同级;已是根 → 将 上一个同级节点及其子树 挂到当前节点下 |
| 下移一级 | 挂到 display 中 上一个同级节点 的子树末尾 |
菜单项 按节点动态过滤——不可用时隐藏;至少一项可用时才显示 settings 按钮。
asyncRowMutation.move 与 hierarchyChanges
配置了 asyncRowMutation.move 时,拖拽 mouseup 后先 await move(source: 'uiRowDrag'),成功才写 source。
树形改挂、快捷菜单等操作常使 moves 为空 而 hierarchyChanges 非空:
import { getRowDragCommitHierarchy } from '@taocompany/magic-grid'
async function persistMove(params: AsyncRowMutationMoveParams): Promise<void> {
// 推荐:过滤掉仅 treeLevel 变化的项,持久化 parentId + order
const changes = getRowDragCommitHierarchy(params, 'noLevel')
await api.saveHierarchy({ changes })
}
RowHierarchyChange 含 rowId、parentRowId、siblingIndex、treeLevel 等字段,由 asyncRowMutation.move 在 source: 'uiRowDrag' 时传入。
树形与其它能力叠加
| 场景 | 预期行为 |
|---|---|
| 固定列 / 列虚拟化 | tree 列默认左固定;tree cell 仍受列窗口约束 |
| 行虚拟化 | 全部 display 行参与 rowTop 累计;百万行靠虚拟化 |
| Master Detail | detail 行紧跟 master leaf;不参与 tree 路径与子树计数 |
| 合并单元格 | tree 行 不参与 colSpan/rowSpan |
| 单元格编辑 | 所有 data 行可编辑(含父节点);group 模式下的 leaf 限制 不适用 |
| 索引列 | 对 全部 display 行连续编号 |
| cellComments / 框选 / 剪贴板 | 与 flat 相同,基于 display 索引 |
| rowGrouping | 互斥 · 勿双开 |
常见错误与排查
| 现象 | 可能原因 | 处理 |
|---|---|---|
初始化 throw tree: true requires getDataPath |
未传 getDataPath |
添加回调 |
refresh throw missing parent path |
子行路径缺父节点行 | 补全中间层或修正 path |
| refresh throw 重复路径 | 两行 getDataPath 相同 |
保证路径唯一 |
| 双开 tree + rowGrouping 但无分组 | 设计如此,tree 优先 | 二选一 |
| lazy 展开无 chevron | 未传 hasTreeChildren 且 source 无子行 |
提供 hasTreeChildren |
| lazy 展开无反应 | 未传 loadTreeChildren |
检查 dev 警告 |
| hierarchy drag 无效 | 未传 setDataPath |
实现写回或使用默认 pathSegments |
| 跨父 drag 被拒绝 | treeDragScope: 'siblings' |
改为 hierarchy |
| 选中父但子孙未选中 | 子孙折叠不可见,或 groupSelectsChildren: false |
展开 / 检查配置 |
expandAll 未加载 lazy 子级 |
设计限制 | 逐节点 expand 或预加载 |
相关 API 索引:Props · 树形表格 · Events · 树形表格 · GridApi · expandNode。
默认配置
以下为 <MagicGrid> 未显式传入 prop 时的生效值。部分 prop 在组件层与内核层默认不同(标注 MG = MagicGrid 组件层覆盖),使用时以组件行为为准。
尺寸 preset(size)
rowHeight / headerHeight / statusBarHeight(statusBarHeight: 'auto' 时)未显式传入时,由 size 推导:
size |
行高 | 表头高 | 状态栏高 | 字号 | 间距 | 圆角(rounded: true 时) |
|---|---|---|---|---|---|---|
mini |
20 | 20 | 20 | 12 | 4 | 4 |
small |
24 | 24 | 24 | 12 | 8 | 8 |
default |
32 | 32 | 32 | 12 | 8 | 8 |
large |
40 | 40 | 40 | 14 | 12 | 8 |
基础与外观
| 配置项 | 默认值 | 说明 |
|---|---|---|
rowKey |
'id' |
行主键字段 |
height / width |
'100%' |
容器尺寸;number 或纯数字字符串(如 "420")自动补 px |
stripe |
false |
斑马纹 |
border |
'border' |
全网格线 |
theme |
'light' |
亮色主题 |
size |
'default' |
尺寸 preset |
rounded |
false |
无圆角(0) |
rowHeight / headerHeight |
— | 跟随 size preset |
summaryRowHeight |
— | 跟随 rowHeight |
对齐
| 配置项 | 默认值 |
|---|---|
headerAlign / headerValign |
'center' |
align / valign |
'center' |
footerAlign / footerValign |
'center' |
虚拟化与导航
| 配置项 | 默认值 | 说明 |
|---|---|---|
rowBuffer |
10 |
行虚拟化缓冲行数 |
scrollEndFlushMs |
0 |
滚动停止后 flush RAF(ms);0 = 关闭 |
frameBudgetMs |
60 |
活跃滚动帧预算(ms) |
scrollEndFrameBudgetMs |
-1 |
idle flush 帧预算;-1 = 一次跑完 |
cellRendererDefer |
'always' |
cellRenderer 调度策略 |
deferRowDestroyOnScroll |
false |
滚动 active 期间延迟行 destroy |
rendererFrameBudgetMs |
20 |
滚动 active 时 f1 每帧保底预算(ms) |
cellRendererPresentation |
'deferred' |
Vue renderer 呈现策略 |
navigateHeader |
false |
不允许焦点进入表头 |
navigateFooter |
false |
不允许焦点进入表尾 |
enableHeaderHighlight |
true |
框选时表头列高亮 |
enableIndexColumnHighlight |
true |
框选时索引列高亮 |
索引列
| 配置项 | 默认值 | 说明 |
|---|---|---|
showIndexColumn |
false |
不显示索引列 |
indexColumn.label |
'' |
表头文案 |
indexColumn.width |
40 |
列宽 px(最小 40) |
indexColumn.start |
1 |
起始序号 |
indexColumn.focusMode |
'multiple' |
辅助定位模式 |
indexColumn.syncToSelectionColumn |
true (MG) |
索引定位单向同步行选择;用户点击索引列或 setIndexFocus(mode: 'default')时生效 |
indexColumn.showRowDragHandle |
false |
不显示行拖拽把柄 |
indexColumn.enableRowResizer |
false |
不可拖拽调整行高 |
行选择
| 配置项 | 默认值 | 说明 |
|---|---|---|
rowSelection |
'single' |
单选模式 |
selectionColumn.width |
40 |
列宽 px |
selectionColumn.selectAllLabel |
'全选' |
全选 checkbox aria-label |
reserveSelection |
false |
数据刷新后是否保留选中行;离屏选中可用 clearRowSelection({ scope: 'all' }) 清空 |
rowSelection 对象形式时,groupSelectsChildren 默认 true(tree 模式父节点级联子孙)。
表尾汇总
| 配置项 | 默认值 | 说明 |
|---|---|---|
showSummary |
false |
不展示汇总行 |
summaryScope |
'displayed' |
按当前可见行汇总 |
排序 / 筛选 / 列操作
| 配置项 | 默认值 | 说明 |
|---|---|---|
sortable |
false |
全列默认不可排序 |
filterable |
false |
全列默认不可筛选 |
resizable |
true |
全列默认可调整列宽 |
columnMovable |
true |
全列默认可拖拽重排 |
quickFilterText |
'' |
无 quick filter |
floatingFilter |
false |
无 floating filter 行 |
filterSetValueMode |
'current' |
值选择勾选投影模式 |
filterSetDateLayoutMode |
'tree' |
日期列值选择树形展示 |
colResizeDefault |
— | 未启用 Shift 邻列补偿 |
skipHeaderOnAutoSize |
false |
auto-size 含表头宽度 |
autoSizePadding |
16 |
auto-size 额外 padding(px) |
suppressMoveWhenColumnDragging |
false |
drag 过程中 live move |
suppressColumnMoveAnimation |
false |
列移动有过渡动画 |
allowCrossLaneColumnMove |
false |
不可跨 fixed lane 移动 |
showUnsortedSortHintOnHover |
false |
未排序列 hover 无双三角提示 |
编辑
| 配置项 | 默认值 | 说明 |
|---|---|---|
editBehavior |
'cell' |
单格编辑 |
editType |
'singleClick' |
单击进入编辑 |
invalidEditValueMode |
'block' |
校验失败保持编辑态 |
行拖拽与行高
| 配置项 | 默认值 | 说明 |
|---|---|---|
rowDragManaged |
true |
managed 拖拽实时改序 |
asyncRowMutation.move |
— | 拖拽与 API 均 await 持久化后再改本地 |
rowHeightMin |
— | 跟随 size / rowHeight |
rowHeightMax |
— | 无上限 |
合并 / 展开 / 分组 / 树
| 配置项 | 默认值 | 说明 |
|---|---|---|
enableCellSpan |
false |
不启用单元格合并 |
masterDetail |
false |
不启用主从展开 |
masterDefaultExpanded |
0 |
默认不展开(启用 masterDetail 后) |
detailRowHeight |
200 |
详情行高度 px |
detailRowAutoHeight |
false |
详情行固定高度 |
embedFullWidthRows |
false |
详情 overlay 不随横滚 |
showExpandColumn |
false |
不展示专用展开列 |
rowGrouping |
false |
不启用行分组 |
groupDefaultExpanded |
-1 |
全部分组默认展开 |
showGroupHeader / showGroupFooter |
false |
不展示分组头/尾行 |
groupDisplayType |
'singleColumn' |
单列分组展示 |
showGroupColumn |
false |
不展示 auto group 列 |
tree |
false |
不启用树形表格 |
showTreeColumn |
true |
展示 tree 系统列(启用 tree 后) |
treeDragScope |
'siblings' |
树拖拽仅同层兄弟 |
treeHierarchyActions |
true |
hierarchy 模式下展示层级快捷菜单 |
treeDisplayType |
'singleColumn' |
单列树展示 |
treeLazyLoad |
false |
不启用懒加载 |
批注
| 配置项 | 默认值 | 说明 |
|---|---|---|
suppressCellComments |
false |
不抑制批注 |
cellCommentTrigger |
'click' |
点击角标查看 |
cellCommentShowDelay |
180 |
hover 展示延迟 ms |
cellCommentHideDelay |
220 |
离开隐藏延迟 ms |
框选与剪贴板
| 配置项 | 默认值 | 说明 |
|---|---|---|
cellSelection |
true (MG) |
启用框选(Grid API 直连默认 false) |
cellSelection.enableColumnSelection |
true (MG) |
点击表头选中整列(Grid API 默认 false) |
cellSelection.suppressMultiRanges |
true |
仅允许单个 range |
cellSelection.handleMode |
'off' |
无 Fill/Range 拖拽柄 |
cellSelection.direction |
'xy' |
fill 方向(handleMode 为 fill 时) |
cellSelection.fillStrategy |
'copy' |
填充策略 |
cellSelection.fillReverseStrategy |
'default' |
反拖缩小行为 |
enableCellCopy |
true |
Ctrl+C / 复制 API |
enableCellPaste |
false |
Ctrl+V / 粘贴 API |
Tooltip
| 配置项 | 默认值 | 说明 |
|---|---|---|
enableTooltips |
true |
启用溢出 tooltip |
tooltipShowMode |
'whenTruncated' |
仅溢出时展示 |
tooltipShowDelay |
500 |
首次 hover 延迟 ms |
tooltipSwitchShowDelay |
200 |
格间切换延迟 ms |
tooltipHideDelay |
3000 |
离开后隐藏延迟 ms |
tooltipInteraction |
false |
tooltip 不可交互 |
tooltipMouseTrack |
false |
tooltip 不跟随鼠标 |
空态 Overlay
| 配置项 | 默认值 | 说明 |
|---|---|---|
loading |
undefined |
挂载后首次 setData 前自动 loading |
overlayInteraction |
false |
overlay 内容不可交互 |
状态栏
| 配置项 | 默认值 | 说明 |
|---|---|---|
showStatusBar |
true |
显示底部状态栏 |
showDefaultStatusBarPanels |
true |
显示默认左侧面板 |
statusBarHeight |
'auto' |
跟随 size preset |
showStatusBarRangeAggregation |
true |
框选时展示聚合 |
statusBarRangeAggregationPosition |
'right' |
聚合 panel 在右栏 |
statusBarRangeAggregationPrecision |
2 |
平均值/求和各 2 位小数 |
ColumnDef 列级默认
| 字段 | 默认值 | 说明 |
|---|---|---|
available |
true |
列有效;false 时不进入列模型(表格中无此列) |
hidden |
false |
列可见;true 时仍在列模型中但不渲染(可 API/菜单恢复) |
sortable / filterable |
继承 Grid 级(默认 false) |
列级显式配置优先 |
resizable / movable |
继承 Grid 级(默认 true) |
列级显式配置优先 |
filterType |
'text' |
文本筛选 |
cellEditorMode |
'overlay' |
编辑 overlay 呈现 |
editType |
继承 Grid 级 | — |
useParserForClipboard |
true |
粘贴走 valueParser |
useFormatterForClipboard |
true |
复制走 formatter |
summary |
有 summaryAgg 时为 true |
否则 false |
| 对齐字段 | 'center' |
header / body / footer |
Props
各 prop 的默认值汇总见上一节 默认配置。下列按功能分组逐项说明类型、默认值与行为。
MagicGrid Props
基础
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
columns |
ColumnDef[] |
— | 必填。列定义数组;available: false 的项仍可在 prop 中保留,但不会进入 Grid 列模型 |
data |
RowData[] |
— | 必填。行数据(普通对象,禁止 reactive 深代理) |
rowKey |
string |
'id' |
行主键字段名,用于行池复用与增量更新 |
height |
string | number |
'100%' |
容器高度;number / 纯数字字符串 → px,亦支持 % / vh 等 |
width |
string | number |
'100%' |
容器宽度;解析规则同 height |
外观
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
stripe |
boolean |
false |
斑马纹 |
border |
'border' | 'none' | 'linear' |
'border' |
边框样式:border 全网格线;none 无单元格线;linear 仅底部分隔线 |
theme |
'light' | 'dark' |
'light' |
主题 preset |
size |
'mini' | 'small' | 'default' | 'large' |
'default' |
尺寸 preset(影响行高、字号、间距等) |
rounded |
number | boolean |
false |
容器圆角:false/0 无圆角;true 跟随 size;number 自定义 px |
rowHeight |
number |
— | 固定行高(px);显式传入时覆盖 size preset |
headerHeight |
number |
— | 表头高度(px);显式传入时覆盖 size preset |
rowStyle |
RowStyle | RowStyleFn |
— | 行级样式(对象=全表同色;函数=按行);作用于表体用户数据列与行选择列 |
对齐(全局默认)
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
headerAlign |
'left' | 'center' | 'right' |
'center' |
表头水平对齐 |
headerValign |
'top' | 'center' | 'bottom' |
'center' |
表头垂直对齐 |
align |
'left' | 'center' | 'right' |
'center' |
表体水平对齐 |
valign |
'top' | 'center' | 'bottom' |
'center' |
表体垂直对齐 |
footerAlign |
'left' | 'center' | 'right' |
'center' |
表尾汇总水平对齐 |
footerValign |
'top' | 'center' | 'bottom' |
'center' |
表尾汇总垂直对齐 |
虚拟化与导航
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
rowBuffer |
number |
10 |
行虚拟化缓冲行数 |
scrollEndFlushMs |
number |
0 |
滚动停止 debounce 后 flush RAF(ms);0 = 关闭 |
frameBudgetMs |
number |
60 |
活跃滚动时每帧任务预算(ms) |
scrollEndFrameBudgetMs |
number |
-1 |
scroll idle flush 帧预算;-1 = 一次跑完 |
cellRendererDefer |
'always' | 'never' | 'sync-only' |
'always' |
cellRenderer 是否进入 f1 异步队列 |
deferRowDestroyOnScroll |
boolean |
false |
滚动 active 期间延迟行 destroy + Vue unmount |
rendererFrameBudgetMs |
number |
20 |
滚动 active 时为 f1 预留的每帧保底预算(ms);0 = 与 p1/p2 共享 |
cellRendererPresentation |
'immediate' | 'deferred' | 'placeholder-then-vue' |
'deferred' |
Vue renderer 呈现策略;详见 Cell Renderer 滚动渲染 |
navigateHeader |
boolean |
false |
是否允许键盘/鼠标将焦点导航到表头 |
navigateFooter |
boolean |
false |
是否允许焦点导航到表尾汇总行(需 showSummary: true) |
enableHeaderHighlight |
boolean |
true |
表头高亮 |
enableIndexColumnHighlight |
boolean |
true |
索引列高亮 |
索引列
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
showIndexColumn |
boolean |
false |
是否显示最左侧索引列;asyncRowMutation await 期间 loading 亦依赖此项 |
indexColumn |
IndexColumnOptions |
— | 索引列配置(showIndexColumn=true 时生效) |
IndexColumnOptions 字段:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
label |
string |
'' |
表头文案 |
width |
number |
40 |
列宽 px(最小 40) |
start |
number |
1 |
起始序号(1-based 展示 = rowIndex + start) |
focusMode |
'single' | 'multiple' |
'multiple' |
辅助定位模式 |
syncToSelectionColumn |
boolean |
false(MagicGrid 组件层默认 true) |
索引列定位是否单向同步到行选择列;仅当 focusMode 与 rowSelection 同为 single 或同为 multiple 时生效。用户在索引列上操作,或 API setIndexFocus(mode: 'default')时同步;点击其他区域清除索引定位、行删除 / rowId 迁移等不同步 |
index |
(rowIndex) => number | string |
— | 自定义序号展示 |
showRowDragHandle |
boolean |
false |
在索引列显示行拖拽把柄 |
enableRowResizer |
boolean |
false |
索引列底边可拖拽调整行高 |
headerAlign / headerValign / align / valign / footerAlign / footerValign |
GridHorizontalAlign / GridVerticalAlign |
'center' |
对齐配置 |
行选择
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
rowSelection |
'single' | 'multiple' | false | RowSelectionConfig |
'single' |
行选择模式;false 禁用 |
selectionColumn |
SelectionColumnOptions |
— | 行选择列配置 |
selectable |
SelectableFn |
— | 行 checkbox 是否可勾选;省略时全部可选 |
reserveSelection |
boolean |
false |
数据刷新后是否保留选中行;离屏选中可用 clearRowSelection({ scope: 'all' }) 清空 |
isRowDisabled |
boolean | IsRowDisabledFn |
— | 行级禁用(该行全部数据列 disabled) |
defaultSelectedRows |
DefaultSelectedRowsInput |
— | preset 默认选中:id 数组或解析函数;写入 pending,行就绪后 reconcile(cover)。addRows 分块见同文档 §12。 docs/50-default-selected-rows.md |
RowSelectionConfig:
interface RowSelectionConfig {
mode: 'single' | 'multiple'
groupSelectsChildren?: boolean // tree 模式下选中父节点是否级联子孙,默认 true
}
SelectionColumnOptions 字段:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
width |
number |
40 |
列宽 px(最小 40) |
selectAllLabel |
string |
'全选' |
表头全选 checkbox 的 aria-label |
rowLabel |
(rowIndex) => string |
— | 行 checkbox 的 aria-label 工厂 |
headerAlign / headerValign / align / valign / footerAlign / footerValign |
GridHorizontalAlign / GridVerticalAlign |
'center' |
对齐配置 |
表尾汇总
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
showSummary |
boolean |
false |
是否展示表尾汇总行 |
summaryScope |
'displayed' | 'all' |
'displayed' |
汇总范围:displayed 当前可见行;all 全量 sourceRows |
summaryRowHeight |
number |
— | 汇总行高度 px;未传时跟随 rowHeight |
summaryMethod |
SummaryMethod |
— | 全局汇总方法(优先级高于列级 summaryAgg) |
排序
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
defaultSort |
SortModelItem[] |
— | 初始排序(挂载时应用一次;v1 仅使用首项) |
sortable |
boolean |
false |
是否允许表头排序;列级 columns[].sortable 优先于本配置;系统列恒为 false |
showUnsortedSortHintOnHover |
boolean |
false |
未排序 sortable 列 hover 显示 faint 双三角 |
列操作
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
columnMovable |
boolean |
true |
是否允许表头拖拽重排列 |
resizable |
boolean |
true |
是否允许拖拽调整列宽(列级 resizable 优先) |
colResizeDefault |
'shift' |
— | Shift 模式:拖拽列宽时相邻列反向补偿,总宽不变 |
skipHeaderOnAutoSize |
boolean |
false |
双击 resize 把柄 auto-size 时跳过表头宽度 |
autoSizePadding |
number |
16 |
auto-size 内容测量额外 padding(px) |
autoSizeStrategy |
AutoSizeStrategy |
— | 挂载/首屏 auto-size 策略(见 AutoSizeStrategy) |
suppressMoveWhenColumnDragging |
boolean |
false |
true → 仅 mouseup 提交列序 |
suppressColumnMoveAnimation |
boolean |
false |
关闭列移动 transition |
allowCrossLaneColumnMove |
boolean |
false |
允许 drag/API 跨 fixed lane 并更新列 fixed |
筛选
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
filterable |
boolean |
false |
是否允许列筛选;列级 columns[].filterable 优先于本配置;系统列恒为 false |
quickFilterText |
string |
'' |
Grid 级 quick filter 文本(对 filterable 用户列 OR 式 contains) |
floatingFilter |
boolean |
false |
表头下方 floating filter 行(仅对 filterable 列渲染输入框) |
filterSetValueMode |
'reserve' | 'current' |
'current' |
值选择搜索时的勾选投影模式 |
filterSetDateLayoutMode |
'list' | 'tree' |
'tree' |
日期列值选择展示方式 |
编辑
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
editBehavior |
CellEditBehavior |
'cell' |
编辑范围:单格 / 整行 |
editType |
CellEditType |
'singleClick' |
进入编辑态的触发方式 |
invalidEditValueMode |
'block' | 'revert' | 'keep' |
'block' |
校验失败后:block 保持编辑;revert 退出并恢复旧值;keep 退出编辑但保留无效值 |
rowValidator |
RowValidator |
— | 行编辑跨字段校验 |
cellEditorRegistry |
Record<string, CellEditorFn> |
— | 实例级命名编辑器注册表 |
asyncRowMutation |
AsyncRowMutationHandlers |
— | 异步行 CRUD 持久化钩子(见 AsyncRowMutationHandlers) |
行拖拽与行高
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
rowDragManaged |
boolean |
true |
managed 行拖拽:拖拽过程中实时改 source 顺序 |
asyncRowMutation |
AsyncRowMutationHandlers |
— | 含 move 时编程式 move 与索引列拖拽共用;await 期间索引列 loading(须 showIndexColumn) |
getRowHeight |
GetRowHeightFn |
— | 行级动态高度(无 DOM) |
rowHeightMin |
number |
— | 行高下限 px |
rowHeightMax |
number |
— | 行高上限 px |
合并单元格
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
enableCellSpan |
boolean |
false |
启用单元格合并(列级 colSpan / rowSpan / spanRows) |
主从展开行
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
masterDetail |
boolean |
false |
启用主从展开行 |
isRowMaster |
IsRowMasterFn |
— | 是否为主行(可展示 expand 控件) |
masterDefaultExpanded |
number |
— | 默认展开层级:0=无;1=第一层;-1=全部 |
detailRowHeight |
number | DetailRowHeightFn |
— | 详情行固定高度 px |
detailRowAutoHeight |
boolean |
— | 详情行按内容自动撑高 |
embedFullWidthRows |
boolean |
— | true:详情嵌入 center lane 随横滚 |
showExpandColumn |
boolean |
— | 最左展示专用展开列 |
getDetailRowData |
GetDetailRowDataFn |
— | 异步提供详情区数据 |
detailCellRenderer |
DetailCellRendererFn |
— | 自定义详情行渲染器(与 #detail-row 插槽二选一) |
行分组
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
rowGrouping |
boolean |
false |
启用行分组 |
groupDefaultExpanded |
number |
-1 |
默认展开分组层级:0=全折叠;1=第一层;-1=全部 |
showGroupHeader |
boolean |
false |
展示 groupHeader 分组标题行 |
showGroupFooter |
boolean |
false |
为每个已展开分组展示 footer 汇总行 |
groupDisplayType |
'singleColumn' |
'singleColumn' |
分组展示模式(v1 仅 singleColumn) |
showGroupColumn |
boolean |
false |
展示 auto group 系统列 |
autoGroupColumnDef |
Partial<ColumnDef> |
— | 覆盖 auto group 列 colDef |
groupKeyCreator |
GroupKeyCreatorFn |
— | 分组键归一化 |
groupComparator |
GroupComparatorFn |
— | 同级 group 节点排序 |
groupFooterLabel |
string |
— | groupFooter 首列展示标签 |
groupCellRenderer |
GroupCellRendererFn |
— | 自定义分组单元格渲染器 |
编辑:启用单元格编辑时,仅 leaf 数据行可进入编辑态;
groupHeader/groupFooter不渲染 inline 或 overlay 编辑器(由isCellEditable+cellCtrl共同保证)。
树形表格
完整消费端指南见 树形表格 专章(概念、懒加载、拖拽、排查)。下表为 Props 速查。
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
tree |
boolean |
false |
启用树形表格(与 rowGrouping 互斥) |
getDataPath |
GetDataPathFn |
— | 树形路径回调(tree: true 时 必填) |
groupDefaultExpanded |
number |
-1 |
默认展开层级:0 全折叠 · 1 第一层 · -1 全部(tree / group 共用) |
treeDragScope |
'siblings' | 'hierarchy' |
'siblings' |
树形拖拽范围;hierarchy 允许跨父改挂(需 setDataPath) |
setDataPath |
SetDataPathFn |
— | hierarchy 模式下写回 dataPath 到行数据 |
treeHierarchyActions |
boolean |
true |
hierarchy 时在 tree 列展示 上移一级 / 下移一级 菜单 |
showTreeColumn |
boolean |
true |
展示 tree 系统列(colId __tree__) |
autoTreeColumnDef |
Partial<ColumnDef> |
— | 覆盖 tree 系统列 colDef |
treeValueGetter |
TreeValueGetterFn |
— | 自定义 tree 列展示值(缺省为 dataPath 末段) |
treeDisplayType |
'singleColumn' |
'singleColumn' |
树节点展示列模式 |
treeLazyLoad |
boolean |
false |
启用树形懒加载(CSRM · 需 loadTreeChildren) |
hasTreeChildren |
HasTreeChildrenFn |
— | lazy:节点是否可能有未加载子行(控制 chevron) |
loadTreeChildren |
LoadTreeChildrenFn |
— | lazy:首次展开时拉取子数据 |
单元格批注
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
cellCommentsDataSource |
CellCommentsDataSource |
— | 批注数据源;提供即启用(见 CellCommentsDataSource) |
suppressCellComments |
boolean |
false |
全局抑制批注交互 |
cellCommentTrigger |
'click' | 'hover' |
'click' |
查看已有批注的触发方式 |
cellCommentShowDelay |
number |
180 |
hover 模式展示延迟 ms |
cellCommentHideDelay |
number |
220 |
离开 cell/popup 后隐藏延迟 ms |
框选与剪贴板
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
cellSelection |
boolean | CellSelectionOptions |
true |
单元格框选;MagicGrid 默认开启、enableColumnSelection 为 true、handleMode 为 off;Grid API 未传时默认关闭 |
enableCellCopy |
boolean |
true |
Ctrl+C / copySelectedRangeToClipboard |
enableCellPaste |
boolean |
false |
Ctrl+V / pasteFromClipboard |
processCellForClipboard |
ProcessCellForClipboardFn |
— | 复制单格时自定义导出值 |
processCellFromClipboard |
ProcessCellFromClipboardFn |
— | 粘贴单格时预处理 clipboard 字符串 |
processDataFromClipboard |
ProcessDataFromClipboardFn |
— | 整表粘贴前处理 TSV 矩阵;return null 取消粘贴 |
CellSelectionOptions 字段(cellSelection 为对象时):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
suppressMultiRanges |
boolean |
true |
true 时仅允许单个 range |
enableColumnSelection |
boolean |
MagicGrid true / Grid API false |
点击表头选中整列 |
handleMode |
'off' | 'fill' | 'range' |
'off' |
Fill / Range 拖拽柄 |
direction |
'x' | 'y' | 'xy' |
'xy' |
handleMode: 'fill' 时填充方向 |
fillStrategy |
'auto' | 'copy' |
'copy' |
'auto':数字递增、非数字复制;'copy':始终复制源边值 |
fillReverseStrategy |
'default' | 'clear' |
'default' |
反拖缩小时:'default' 不处理;'clear' 置空缩出初始选区的格 |
setFillValue |
(params: FillOperationParams) => unknown |
— | 自定义填充值;缺省按 fillStrategy |
FillOperationParams:{ rowNode, column, baseValue, step, direction }。
框选行为要点:
- 鼠标拖拽或 Shift+方向键扩展选区;
suppressMultiRanges: true时仅保留单个 range。 enableColumnSelection: true时点击表头选中整列;MagicGrid 默认开启。handleMode: 'fill'启用填充柄;'range'启用范围扩展柄;'off'无柄(MagicGrid 默认)。- Delete 键清空选区内可编辑格,触发
cell-selection-delete-start/cell-selection-delete-end。 - Ctrl+C /
copySelectedRangeToClipboard复制 TSV;Ctrl+V /pasteFromClipboard粘贴(需enableCellPaste: true)。
Tooltip
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
enableTooltips |
boolean |
true |
是否启用溢出 tooltip |
tooltipShowMode |
'whenTruncated' | 'always' | 'never' |
'whenTruncated' |
溢出 tooltip 显示策略 |
tooltipShowDelay |
number |
500 |
首次 hover 展示延迟 ms |
tooltipSwitchShowDelay |
number |
200 |
格间切换展示延迟 ms |
tooltipHideDelay |
number |
3000 |
离开后隐藏延迟 ms |
tooltipInteraction |
boolean |
— | tooltip 是否可交互 |
tooltipMouseTrack |
boolean |
— | tooltip 是否跟随鼠标 |
tooltipComponent |
TooltipComponentType |
— | 自定义 tooltip 组件(与 #tooltip 插槽二选一) |
tooltipComponentParams |
Record<string, unknown> |
— | tooltip 组件额外参数 |
空态 Overlay
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
loading |
boolean |
— | 显示 loading overlay;undefined 为挂载后首次 setData 前自动 loading |
suppressOverlays |
OverlayType[] |
— | 逐项抑制内置 overlay |
suppressLoadingOverlay |
boolean |
— | 抑制 loading overlay |
suppressNoRowsOverlay |
boolean |
— | 抑制无数据 overlay |
suppressNoMatchingRowsOverlay |
boolean |
— | 抑制筛选无匹配 overlay |
overlayLoadingTemplate |
string |
— | loading 模板 HTML |
overlayNoRowsTemplate |
string |
— | 无数据模板 HTML |
overlayNoMatchingRowsTemplate |
string |
— | 筛选无匹配模板 HTML |
loadingOverlayComponent |
OverlayComponentType |
— | 自定义 loading 组件 |
loadingOverlayComponentParams |
Record<string, unknown> |
— | loading 组件额外参数 |
noRowsOverlayComponent |
OverlayComponentType |
— | 自定义无数据组件 |
noRowsOverlayComponentParams |
Record<string, unknown> |
— | 无数据组件额外参数 |
noMatchingRowsOverlayComponent |
OverlayComponentType |
— | 自定义筛选无匹配组件 |
noMatchingRowsOverlayComponentParams |
Record<string, unknown> |
— | 筛选无匹配组件额外参数 |
overlayComponent |
OverlayComponentType |
— | 通用 overlay 组件 |
overlayComponentParams |
Record<string, unknown> |
— | 通用 overlay 组件额外参数 |
overlayInteraction |
boolean |
— | overlay 内容是否可交互 |
状态栏
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
showStatusBar |
boolean |
true |
是否显示底部状态栏 |
statusBarHeight |
'auto' | number |
'auto' |
状态栏高度;auto 跟随 size preset |
showDefaultStatusBarPanels |
boolean |
true |
显示默认状态栏左侧面板(行数/筛选态/选中数);false 时仍可自定义 #status-bar-left |
showStatusBarRangeAggregation |
boolean |
true |
框选时在状态栏展示平均值/计数/求和 |
statusBarRangeAggregationPosition |
'left' | 'right' |
'right' |
框选聚合 panel 位置(左栏/右栏内侧) |
statusBarRangeAggregationPrecision |
number | { average?: number; sum?: number } |
2 |
平均值/求和展示小数位数 |
Grid 级默认与列级覆盖
以下 Grid Prop 可一次性为所有用户列设定默认行为;列级字段显式配置时以列为准(对齐 AG Grid defaultColDef 语义):
| Grid Prop | 列级字段 | 默认值 | 说明 |
|---|---|---|---|
sortable |
columns[].sortable |
false |
表头点击排序 |
filterable |
columns[].filterable |
false |
列筛选 / 表头 filter 把柄 / quick filter 参与列 |
resizable |
columns[].resizable |
true |
拖拽调整列宽 |
columnMovable |
columns[].movable |
true |
表头拖拽重排列 |
系统列(索引 / 行选择 / 展开 / 分组等)不受 Grid 默认影响,相关能力恒为关闭。
运行时修改 :sortable / :filterable / :resizable 会热更新列模型并刷新表头(无需重建 Grid)。
<!-- 全列默认可排序、可筛选;金额列单独关闭 -->
<MagicGrid
:columns="[
{ prop: 'name', label: '名称' },
{ prop: 'amount', label: '金额', sortable: false, filterable: false },
]"
sortable
filterable
floating-filter
/>
ColumnDef 列定义
每列通过 columns 数组传入。key 为列唯一标识,缺省等于 prop。
标识与展示
| 字段 | 类型 | 说明 |
|---|---|---|
key |
string |
列唯一标识(colId),缺省等于 prop |
prop |
string |
数据字段 |
label |
string |
表头文案 |
列有效性与显隐
通过 available 与 hidden 控制列是否参与表格。二者均可在 columns prop 中动态修改;Grid 会重解析列模型并刷新布局。
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
available |
boolean |
true |
false 时该列不存在于表格(解析前从列模型裁剪 · 不参与布局/DOM · 无 setColumnsHidden) |
hidden |
boolean |
false |
true 时列仍在列模型中,仅不渲染(可通过 setColumnsHidden / 列菜单 / 列设置面板恢复) |
语义对照:
available: false |
hidden: true |
|
|---|---|---|
getColumns() |
不含该列 | 含该列 |
getDisplayedColumns() |
不含 | 不含 |
| DOM / 布局 | 不参与 | 不参与 |
setColumnsHidden |
不适用(列不在模型中) | 可恢复显示 |
| sort / filter 模型 | 不应再引用该 colId | 仍可保留 · 表头无 UI |
| 列设置面板 | 不出现(未注册进模型) | 出现在「隐藏」分组 |
| 典型用途 | 按权限/场景裁剪列定义 | 用户临时隐藏列 |
const columns: ColumnDef[] = [
{ prop: 'name', label: '名称' },
// 表格中完全没有这一列(行数据字段可保留)
{ prop: 'internalCode', label: '内部编码', available: false },
// 列仍在模型中,默认隐藏,API/菜单可恢复
{ prop: 'note', label: '备注', hidden: true },
]
// hidden 列:全量 vs 展示
api.getColumns().map((c) => c.colId) // 含 note
api.getDisplayedColumnIds() // 不含 note(除非已显示)
// available: false 的列不在 getColumns() 中
api.getColumns().some((c) => c.colId === 'internalCode') // false
修改 columns 中某列的 available 或 hidden 后,Grid 会走 setColumns 重解析。available 集合变化时列顺序按 ColumnDef 声明序重置;同集合热更新(如仅改 width/label)仍保留 runtime 顺序(含用户拖拽)。hidden 在 columnDefs 未改 hidden 声明时,会保留运行时 API/菜单设置的值(与 Phase 22 列显隐语义一致)。
尺寸
| 字段 | 类型 | 说明 |
|---|---|---|
width |
number |
固定列宽 px |
minWidth |
number |
最小列宽 px |
maxWidth |
number |
最大列宽 px |
flex |
number |
弹性列宽权重 |
行为
| 字段 | 类型 | 说明 |
|---|---|---|
sortable |
boolean |
是否可排序;缺省继承 Grid sortable(默认 false) |
comparator |
ColumnComparatorFn |
自定义排序比较器(asc 语义;desc 由内核取反) |
filterable |
boolean |
是否可筛选;缺省继承 Grid filterable(默认 false) |
filterType |
ColumnDataFilterType |
筛选数据类型;默认 text |
filterParams |
FilterParams |
列级 filter 参数(见 FilterParams) |
filterFormatter |
(row) => unknown |
筛选用取值;缺省 formatter → valueGetter → prop |
editable |
boolean | (row) => boolean |
是否可编辑 |
resizable |
boolean |
是否允许拖拽调整列宽;缺省继承 Grid resizable(默认 true) |
suppressAutoSize |
boolean |
禁止 resize 把柄 dblclick / API auto-size |
suppressSizeToFit |
boolean |
禁止参与 sizeColumnsToFit |
fixed |
'left' | 'right' | null |
固定列 |
movable |
boolean |
是否允许表头拖拽重排;缺省继承 columnMovable |
rowDrag |
boolean |
该列单元格作为行拖拽起点 |
rowExpand |
boolean |
在该列渲染 expand/collapse 控件 |
autoHeight |
boolean |
该列内容撑开行高 |
行分组(需 rowGrouping: true)
| 字段 | 类型 | 说明 |
|---|---|---|
rowGroup |
boolean |
该列参与行分组 |
rowGroupIndex |
number |
多级分组顺序(小者优先) |
groupAgg |
SummaryAgg |
分组 footer 行的聚合 |
showGroupHeaderCell |
boolean |
在该列渲染 groupHeader 单元格 |
showGroupFooterCell |
boolean |
在该列渲染 groupFooter 标签 |
groupFooterLabel |
string |
覆盖 Grid groupFooterLabel 的本列小计文案 |
合并单元格(需 enableCellSpan: true)
| 字段 | 类型 | 说明 |
|---|---|---|
colSpan |
ColSpanFn |
横向合并列数(≥1) |
rowSpan |
RowSpanFn |
纵向合并行数(≥1);与 spanRows 互斥时本字段优先 |
spanRows |
boolean | SpanRowsFunc |
相邻等值自动纵向合并 |
数据转换与渲染
| 字段 | 类型 | 说明 |
|---|---|---|
valueGetter |
(row, value) => unknown |
取值转换 |
formatter |
(row, value) => string |
展示格式化 |
cellRenderer |
CellRendererFn |
自定义单元格渲染器(函数;Vue 组件通过 #cell-{colId} 插槽) |
cellRendererMount |
'vue' | 'sync' |
列级 renderer 挂载类型;配合 cellRendererDefer: 'sync-only' 使用 |
cellEditor |
CellEditorDef |
自定义单元格编辑器(函数、内置 text/number/checkbox/switch、或命名引用) |
cellEditorParams |
CellEditorParamsInput |
列级编辑器配置;checkbox / switch / 自定义编辑器统一入口(见 47-cell-editor-params) |
cellEditorMode |
'overlay' | 'inline' |
编辑器呈现方式;默认 overlay |
valueParser |
(value, params) => unknown |
提交前解析编辑值 |
valueSetter |
(params) => boolean | Promise<boolean> |
自定义写回逻辑;返回 false 拒绝提交 |
cellCommitted |
CellCommittedHandler |
值成功写回后的列级副作用;联动字段推荐 context.api.patchRow;见 44-phase29 |
editType |
CellEditType |
编辑触发策略;缺省继承 grid 级配置 |
校验
| 字段 | 类型 | 说明 |
|---|---|---|
cellValidator |
CellValidator |
手写校验(优先级高于 validationRules) |
validationRules |
ValidationRules |
async-validator 规则 |
validationRequired |
boolean |
必填列;表头文字前显示红色 *(缺省由 validationRules.required 推导) |
剪贴板
| 字段 | 类型 | 说明 |
|---|---|---|
suppressPaste |
boolean | SuppressPasteFn |
禁止粘贴 |
useParserForClipboard |
boolean |
粘贴是否走 valueParser;默认 true |
useFormatterForClipboard |
boolean |
复制是否走 formatter;默认 true |
汇总
| 字段 | 类型 | 说明 |
|---|---|---|
summary |
boolean |
是否参与表尾汇总;缺省:有 summaryAgg 则为 true |
summaryAgg |
SummaryAgg |
表尾汇总聚合:sum/avg/min/max/count 或自定义函数 |
summaryFormatter |
(value) => string |
汇总格专用 formatter |
对齐
| 字段 | 类型 | 说明 |
|---|---|---|
headerAlign / headerValign |
GridHorizontalAlign / GridVerticalAlign |
表头对齐;默认 center |
align / valign |
GridHorizontalAlign / GridVerticalAlign |
表体对齐;默认 center |
footerAlign / footerValign |
GridHorizontalAlign / GridVerticalAlign |
表尾对齐;默认 center |
禁用与样式
| 字段 | 类型 | 说明 |
|---|---|---|
disabled |
boolean |
列级禁用:该列全部数据行 disabled |
cellDisabled |
boolean | CellDisabledFn |
格级禁用;与 disabled / isRowDisabled 叠加 |
cellStyle |
CellStyle | CellStyleFn |
列级静态背景或格级 cellStyle 回调 |
suppressCellComments |
boolean | SuppressCellCommentFn |
抑制该列(或特定行)的批注新建/编辑/删除 |
Tooltip
| 字段 | 类型 | 说明 |
|---|---|---|
tooltipField |
string |
读 row.data[field] 作为 tooltip |
tooltipValueGetter |
TooltipValueGetter |
自定义 tooltip 文案 |
headerTooltip |
string |
表头静态 tooltip |
headerTooltipValueGetter |
HeaderTooltipValueGetter |
表头自定义 tooltip |
suppressTooltip |
boolean |
抑制该列溢出 tooltip |
tooltipComponent |
TooltipComponentType |
列级自定义 tooltip 组件 |
tooltipComponentParams |
Record<string, unknown> |
tooltip 组件参数 |
Options 类型参考
下列类型均可从 @taocompany/magic-grid 导入,供 Props、GridApi 与事件 payload 使用。
IndexColumnOptions
索引列配置,通过 indexColumn prop 传入(showIndexColumn=true 时生效)。
配置了 asyncRowMutation.update / remove / move 时,await 期间受影响行会在索引列显示 loading spinner(.mg-cell--index-loading)。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
label |
string |
'' |
表头文案 |
width |
number |
40 |
列宽 px(最小 40) |
start |
number |
1 |
起始序号(1-based 展示 = rowIndex + start) |
focusMode |
'single' | 'multiple' |
'multiple' |
辅助定位模式 |
syncToSelectionColumn |
boolean |
core false / MagicGrid true |
索引列定位单向同步到行选择列;用户点击索引列或 setIndexFocus(mode: 'default')时生效 |
index |
(rowIndex) => number | string |
— | 自定义序号展示 |
showRowDragHandle |
boolean |
false |
在索引列显示行拖拽把柄 |
enableRowResizer |
boolean |
false |
索引列底边可拖拽调整行高 |
headerAlign / headerValign / align / valign / footerAlign / footerValign |
GridHorizontalAlign / GridVerticalAlign |
'center' |
对齐配置 |
SetIndexFocusOptions
setIndexFocus 的可选第二参数:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
mode |
'default' | 'manual' |
'default' |
default:与用户点击索引列一致,按 grid syncToSelectionColumn 决定是否同步行选择列;manual:由 syncToSelectionColumn 显式控制 |
syncToSelectionColumn |
boolean |
false(仅 mode: 'manual' 时生效) |
是否同步行选择列;可覆盖 grid 配置 |
api.setIndexFocus(2) // 默认模式
api.setIndexFocus(2, { mode: 'default' }) // 同上
api.setIndexFocus(2, { mode: 'manual', syncToSelectionColumn: false }) // 仅定位,不选中
api.setIndexFocus(2, { mode: 'manual', syncToSelectionColumn: true }) // 强制同步选中
api.setIndexFocus([]) // 清除定位
ClearRowSelectionOptions
clearRowSelection 的可选参数:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
scope |
'current' | 'all' |
'all' |
all:清空全部选中(含 reserveSelection 离屏选中);current:仅取消当前 display 中的选中 |
api.clearRowSelection() // 清空全部
api.clearRowSelection({ scope: 'all' }) // 同上
api.clearRowSelection({ scope: 'current' }) // 仅清当前可见 display 中的选中
SelectionColumnOptions
行选择列配置,通过 selectionColumn prop 传入(rowSelection !== false 时生效)。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
width |
number |
40 |
列宽 px(最小 40) |
selectAllLabel |
string |
'全选' |
表头全选 checkbox 的 aria-label |
rowLabel |
(rowIndex) => string |
— | 行 checkbox 的 aria-label 工厂 |
headerAlign / headerValign / align / valign / footerAlign / footerValign |
GridHorizontalAlign / GridVerticalAlign |
'center' |
对齐配置 |
RowSelectionConfig
rowSelection 的对象形式:
interface RowSelectionConfig {
mode: 'single' | 'multiple'
/** tree 模式下选中父节点是否级联子孙,默认 true */
groupSelectsChildren?: boolean
}
CellSelectionOptions
cellSelection 的对象形式(cellSelection: true 等价 {} 并使用默认子项)。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
suppressMultiRanges |
boolean |
true |
仅允许单个 range |
enableColumnSelection |
boolean |
MagicGrid true / Grid API false |
点击表头选中整列 |
handleMode |
'off' | 'fill' | 'range' |
'off' |
Fill / Range 拖拽柄 |
direction |
'x' | 'y' | 'xy' |
'xy' |
handleMode: 'fill' 时填充方向 |
fillStrategy |
'auto' | 'copy' |
'copy' |
数字递增策略 |
fillReverseStrategy |
'default' | 'clear' |
'default' |
反拖缩小行为 |
setFillValue |
(params: FillOperationParams) => unknown |
— | 自定义填充值 |
FillOperationParams:{ rowNode, column, baseValue, step, direction }。
CellRange(addCellRange / getCellRanges 返回值):
interface CellRange {
startRowIndex: number
endRowIndex: number
startColId: string
endColId: string
}
AutoSizeStrategy
挂载 / 首屏列宽策略,通过 autoSizeStrategy prop 传入。三种 discriminated union:
fitGridWidth — 列宽分配至视口:
interface SizeColumnsToFitGridStrategy {
type: 'fitGridWidth'
defaultMinWidth?: number
defaultMaxWidth?: number
columnLimits?: Array<{ colId: string; minWidth?: number; maxWidth?: number }>
}
fitProvidedWidth — 分配至指定宽度:
interface SizeColumnsToFitProvidedWidthStrategy {
type: 'fitProvidedWidth'
width: number
defaultMinWidth?: number
defaultMaxWidth?: number
columnLimits?: Array<{ colId: string; minWidth?: number; maxWidth?: number }>
}
fitCellContents — 按单元格内容 auto-size:
interface SizeColumnsToContentStrategy {
type: 'fitCellContents'
skipHeader?: boolean
colIds?: readonly string[]
defaultMinWidth?: number
defaultMaxWidth?: number
columnLimits?: Array<{ colId: string; minWidth?: number; maxWidth?: number }>
scaleUpToFitGridWidth?: boolean
}
SizeColumnsToFitParams(GridApi.sizeColumnsToFit(params?)):
| 字段 | 类型 | 说明 |
|---|---|---|
gridWidth |
number |
目标宽度 px;缺省为视口宽度 |
defaultMinWidth / defaultMaxWidth |
number |
列宽 clamp 默认值 |
columnLimits |
{ colId, minWidth?, maxWidth? }[] |
单列限制 |
colIds |
`string |
Related Packages
Version History
| Version | Released | License |
|---|---|---|
| 0.12.5 | MIT | |
| 0.12.4 | MIT | |
| 0.12.3 | MIT | |
| 0.12.2 | MIT | |
| 0.12.1 | MIT | |
| 0.12.0 | MIT | |
| 0.11.8 | MIT | |
| 0.11.7 | MIT | |
| 0.11.6 | MIT | |
| 0.11.5 | MIT | |
| 0.11.4 | MIT | |
| 0.11.3 | MIT | |
| 0.11.0 | MIT | |
| 0.10.5 | MIT | |
| 0.10.4 | MIT | |
| 0.10.3 | MIT | |
| 0.10.2 | MIT | |
| 0.10.1 | MIT | |
| 0.10.0 | MIT | |
| 0.9.11 | MIT | |
| 0.9.10 | MIT | |
| 0.9.9 | MIT | |
| 0.9.8 | MIT | |
| 0.9.7 | MIT | |
| 0.9.6 | MIT | |
| 0.9.5 | MIT | |
| 0.9.4 | MIT | |
| 0.9.3 | MIT | |
| 0.9.2 | MIT | |
| 0.9.1 | MIT |
Showing the latest 30 of 70. See every release on npm