| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
columns |
ColumnConfig[] |
— | 列配置,必填 |
value |
TreeNode[] |
[] |
受控数据 |
onChange |
(value: TreeNode[]) => void |
— | 数据变更回调 |
line |
LineConfig |
{} |
连线配置 |
effects |
Effects |
— | 副作用/联动注册函数(Formily 风格),声明各列依赖与派生状态 |
列较多、内容超出容器宽度时会自动出现横向滚动条,无需额外配置。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
title |
ReactNode |
✓ | 列标题,支持字符串、带图标的 JSX 等任意节点 |
dataIndex |
string |
对应 TreeNode 上的字段名。纯操作列(如"操作"列)可不传 |
|
width |
number |
✓ | 列宽(px) |
hasAdd |
boolean |
✓ | 是否在该列显示"添加同级"按钮 |
render |
(props: CellRenderProps) => ReactNode |
✓ | 自定义渲染函数,必填 |
addRender |
(props: ActionRenderProps) => ReactNode |
自定义"添加"按钮渲染,位置固定在单元格下方。不传则使用默认样式 |
render 函数接收的参数:
| 字段 | 类型 | 说明 |
|---|---|---|
value |
string |
当前单元格的值 |
onChange |
(val: string) => void |
更新当前单元格值的回调(已绑定路径) |
node |
TreeNode |
当前树节点的完整数据,可访问 node.children 等 |
path |
string[] |
从根到当前节点的完整路径(节点 id 数组) |
parent |
TreeNode | null |
直接父节点,根层为 null,可读取父级选中值 |
ancestors |
TreeNode[] |
从根到父节点的祖先链(不含当前节点) |
level |
number |
当前层级索引(0 开始),常用于区分不同层级的样式 |
dataIndex |
string | undefined |
当前列的 dataIndex,同一 render 函数服务多列时可区分字段(纯操作列为 undefined) |
onAdd |
() => void |
添加同级节点(已绑定路径和层级) |
onDelete |
() => void |
删除当前行(在"操作"列的 render 里调用) |
isLeaf |
boolean |
是否为最后一列(叶子层级),常用于给末列加特殊样式 |
width |
number |
当前列宽(px),可用于计算内部元素尺寸 |
field |
FieldState |
由 effects 计算出的派生状态(options / disabled / loading 等),无 effects 时为空对象 |
addRender 函数接收的参数:
| 字段 | 类型 | 说明 |
|---|---|---|
onClick |
() => void |
点击回调,触发添加或删除操作 |
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
style |
'curve' | 'straight' |
'curve' |
连线风格 |
color |
string |
'#d9d9d9' |
连线颜色 |
width |
number |
1.5 |
连线粗细(px) |
showSource |
boolean | SourceAnimationOptions |
false |
溯源动画配置 |
溯源动画是一颗水滴沿连线从子节点流向父节点(圆头 + 收成尖的拖尾)。line.showSource 设为 true 用默认配置,设为对象时可自定义:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
color |
string |
跟随 line.color |
水滴颜色。默认连线色偏浅,建议单独指定一个较深/高饱和度的颜色以便可见 |
size |
number |
6 |
水滴头部大小(px) |
tailLength |
number |
28 |
拖尾长度(px),按像素计算,短连线上也保持一致大小 |
speed |
number |
0.004 |
流动速度 |
breatheAmplitude |
number |
1 |
亮度呼吸幅度 0~1 |
breatheCycle |
number |
400 |
呼吸周期(ms) |
在 <CascadingInput effects={...}> 上声明跨层依赖与派生状态,类似 Formily 的 effects。用 $.onValueChange(target, deps, handler) 声明「target 列依赖 deps 列」,target / deps 均为 dataIndex,deps 沿目标节点祖先链解析,因此可跨任意层级(依赖必须是更上层的列)。
handler 可 return { options, disabled, loading } 作为派生状态简写,或在内部用 ctx.setState({...}) 异步写入;render 通过 CellRenderProps.field 读取。派生状态以节点 id 为 key 独立存储。
field 是 patch 合并,不是替换
只要某条路径置起了 loading: true,每一条出口都必须把它关掉(包括提前 return 的分支和 catch 分支),否则残留的 loading 会让该单元格永久停在「加载中」且被禁用。置过 disabled: true 后同理要在恢复分支显式写 disabled: false。
handler 内未捕获的异常引擎会兜底:记 console.error 并自动复位该单元格的 loading,不会变成 unhandled rejection。但业务上的失败降级仍应自己 try/catch。
| 字段 | 类型 | 说明 |
|---|---|---|
onValueChange |
(target: string, deps: string[], handler: (ctx: EffectContext) => FieldState | void | Promise<FieldState | undefined>) => void |
声明「target 列依赖 deps 列」,任一 dep 变化时执行 handler |
onValidate |
(target: string, rule: ValidateRule, deps?: string[]) => void |
声明「target 列的校验规则」。值变化时反应式重算(首次挂载/回显不报),也可经组件 ref 的 validate() 命令式整树触发。rule 返回错误信息字符串即不通过;deps 省略只关注自身值,声明后可跨列校验。建议每列一条(多重判断写在同一 rule 内) |
onValueChange 的 handler 接收的参数(作用于某个具体目标节点):
| 字段 | 类型 | 说明 |
|---|---|---|
value |
any |
目标节点当前值 |
deps |
Record<string, any> |
依赖字段当前值(按 dataIndex,沿祖先链解析) |
node |
TreeNode |
目标节点,其 id 即派生状态的 key |
path |
string[] |
目标节点完整路径 |
initial |
boolean |
是否为该节点首次求值(详情页初始化回显时为 true),用于区分「初始化」与「用户改动上级」,避免误清空回显值 |
setValue |
(val: any) => void |
设置目标节点自身值(清空传 undefined) |
setState |
(patch: FieldState) => void |
合并写入派生状态,异步友好 |
setTreeValue |
(dataIndex: string, val: any) => void |
设置本分支上某祖先/自身字段的值 |
isActive |
() => boolean |
异步返回后判断本次回调是否仍最新(防竞态) |
| 字段 | 类型 | 说明 |
|---|---|---|
options |
any |
供 select 等控件使用的候选项 |
disabled |
boolean |
是否禁用该单元格 |
loading |
boolean |
是否处于异步加载中 |
error |
string |
校验错误信息,由 effects 写入、render 展示;空/undefined 视为通过。与 loading 同为 patch 合并,校验通过时需显式写 error: undefined 清除 |
[key] |
any |
允许挂载任意自定义派生字段 |
校验统一用 $.onValidate(target, rule, deps?) 声明规则,一份声明同时驱动两种时机:
field.error,render 展示(红边 + 提示)。首次挂载/回显不报,等用户改动后才提示,避免刚进来满屏红。ref 调 validate(),强制对所有目标节点(含未改动字段)跑一遍规则,标红并返回 { valid, errors }。通常在提交时调用,不用再手动遍历 value。rule 返回错误信息字符串表示不通过,返回空串/undefined(或不 return)表示通过。必填、格式、跨列校验都用同一套机制,也不绑定任何校验库。
rule 接收的 ValidateContext:
| 字段 | 类型 | 说明 |
|---|---|---|
value |
any |
目标节点当前值 |
deps |
Record<string, any> |
依赖字段当前值(按 dataIndex,沿祖先链解析);仅在声明了 deps 时有内容 |
node |
TreeNode |
目标节点 |
path |
string[] |
目标节点完整路径(节点 id 数组) |
通过 ref 拿到组件命令式句柄:
校验 reaction 与取数 reaction 可并存(引擎按 reaction 索引 + node.id 分别记录),各自 setState 会 patch 合并进同一个 field,互不覆盖。所以「拉 options」(onValueChange)和「校验」(onValidate)可以拆成两条写。