npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@taocompany/magic-grid

v0.12.0

Published

A high-performance virtual table component library for Vue 3

Readme

Magic Grid

面向 Vue 3 的高性能虚拟表格组件库。采用命令式渲染 + 行 DOM 池 + 双轴虚拟化,可稳定承载百万级行数据;API 设计对标 AG Grid 社区版,覆盖排序、筛选、编辑、行分组、树形表格、框选、剪贴板等完整表格能力。

目录


概述

特性

| 类别 | 能力 | |------|------| | 性能 | 行/列双轴虚拟化、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 全量替换。

列定义

  • 动态列用 columns prop 热更新即可;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 | 研发部下前端组 |

路径规则(必须遵守)

  1. 前缀唯一确定父子:['A','B'] 的父路径必须是 ['A'];缺父路径 → 建树 throw。
  2. 同一路径不得对应多行:重复路径 → 建树 throw。
  3. 路径段为任意字符串:可含中文、空格、特殊字符;内核用 \0 拼接做内部 key。
  4. 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) |

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 | `