FxTree 树形控件
FxTree 属于 @fx/components,不依赖任何 UI 框架。内部组合
FxTreeNode(递归)+FxCheckbox+FxIcon+FxCollapseTransition。
用层级结构展示一组数据。
基础用法
基础的树形结构。
可选择
用于节点选择。
WARNING
使用 show-checkbox 时,由于 check-on-click-leaf 默认为 true,点击叶子节点(最末级)会同时切换其勾选状态。
懒加载自定义叶子节点
懒加载模式下,节点的数据在点击后才会请求,因此 Tree 无法预判某节点是否为叶子。默认会给每个节点渲染展开箭头,若是叶子则在点击后消失。你也可以通过 props.isLeaf 提前告知 Tree 某节点是否为叶子,从而避免渲染展开箭头。
多次懒加载
远程懒加载节点数据时可能加载失败。此时可调用 reject 保持节点状态不变,允许再次远程加载。
禁用 checkbox
可将节点的 checkbox 设为禁用。示例中 defaultProps 声明了 disabled 字段,并将部分节点设为 disabled: true,对应的 checkbox 进入禁用态、不可点击。
默认展开与默认勾选
节点可被初始展开或勾选。使用 default-expanded-keys 与 default-checked-keys 分别设置初始展开和初始勾选的节点。注意二者均需配合 node-key 使用,其值为数据对象中某字段名,且该字段值需全树唯一。
节点勾选
示例演示如何获取和设置勾选节点。两种途径:按节点对象或按 key。若按 key 操作,必须设置 node-key。
自定义节点内容
节点内容可自定义,因此可按需加入图标或按钮。自定义节点内容有两种方式:render-content 与作用域插槽。render-content 接收一个返回节点内容的渲染函数(详见 Vue 渲染函数文档)。若使用作用域插槽,作用域参数含 node(TreeNode 对象)与 data(当前节点数据)。注意 render-content 示例依赖 JSX / h 函数支持。
自定义节点类名
可自定义节点类名。通过 props.class 为节点生成自定义类名。
节点过滤
可对树节点进行过滤。调用 Tree 实例的 filter 方法过滤节点,参数为过滤关键字。注意必须设置 filter-node-method,其值为过滤方法。
手风琴
同一层级每次仅可展开一个节点。
拖拽
为 Tree 加上 draggable 属性即可拖拽节点。
API
Attributes
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| data | 树数据 | Array<Record<string, any>> | [] |
| empty-text | 数据为空时显示的文本 | string | 暂无数据 |
| node-key | 每个节点唯一标识的属性名,其值需全树唯一 | string | — |
| props | 数据字段别名配置,见下表 | TreeOptionProps | 见下表 |
| render-after-expand | 是否在首次展开父节点后才渲染子节点 | boolean | true |
| load | 懒加载子节点数据的方法(仅 lazy 为 true 时生效) | (node, resolve, reject) => void | — |
| render-content | 树节点渲染函数 | (h, { node, data, store }) => VNode | VNode[] | — |
| highlight-current | 是否高亮当前节点 | boolean | false |
| default-expand-all | 是否默认展开全部节点 | boolean | false |
| expand-on-click-node | 是否在点击节点时展开/收起;为 false 时仅点击箭头图标才展开/收起 | boolean | true |
| check-on-click-node | 是否在点击节点时勾选/取消勾选;为 false 时仅点击 checkbox 才切换 | boolean | false |
| check-on-click-leaf | 是否在点击叶子节点时勾选/取消勾选 | boolean | true |
| auto-expand-parent | 展开子节点时是否自动展开父节点 | boolean | true |
| default-expanded-keys | 默认展开的节点 key 数组 | Array<string | number> | — |
| show-checkbox | 是否显示 checkbox(节点可选) | boolean | false |
| check-strictly | 显示 checkbox 时,父子节点是否不联动 | boolean | false |
| check-descendants | 与 check-strictly 配合,懒加载场景下仅设置子节点勾选态而不向上联动 | boolean | false |
| default-checked-keys | 默认勾选的节点 key 数组 | Array<string | number> | — |
| current-node-key | 当前选中节点的 key | string | number | — |
| filter-node-method | 过滤节点的方法(配合 filter 实例方法使用;返回 false 的节点被隐藏) | (value, data, node) => boolean | — |
| accordion | 是否每次只展开同级一个节点 | boolean | false |
| indent | 相邻层级节点的水平缩进(像素) | number | 18 |
| icon | 自定义树节点图标:IconString(传给 FxIcon)或组件;默认 ep:caret-right | IconString | Component | — |
| lazy | 是否懒加载子节点(配合 load) | boolean | false |
| draggable | 是否开启节点拖拽 | boolean | false |
| allow-drag | 判断某节点是否可被拖拽(返回 false 则不可拖) | (node) => boolean | — |
| allow-drop | 判断拖拽节点是否可放置到目标节点(type: prev 插入目标前 / inner 插入目标内 / next 插入目标后) | (draggingNode, dropNode, type) => boolean | — |
props(字段别名)
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| label | 指定作为节点标签的字段 | string | (data, node) => string | — |
| children | 指定作为子树的字段 | string | — |
| disabled | 指定节点 checkbox 是否禁用的字段 | string | (data, node) => boolean | — |
| isLeaf | 指定节点是否为叶子(仅懒加载生效) | string | (data, node) => boolean | — |
| class | 自定义节点类名 | string | (data, node) => string | object | — |
Events
| 事件名 | 说明 | 参数 |
|---|---|---|
| node-click | 点击节点时触发 | (data, node, nodeInstance, evt) |
| node-contextmenu | 右键点击节点时触发 | (evt, data, node, nodeInstance) |
| check-change | 节点勾选状态变化时触发 | (data, checked, indeterminate) |
| check | 点击 checkbox 时触发 | (data, { checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys }) |
| current-change | 当前节点变化时触发 | (data, node) |
| node-expand | 节点展开时触发 | (data, node, nodeInstance) |
| node-collapse | 节点收起时触发 | (data, node, nodeInstance) |
| node-drag-start | 拖拽开始时触发 | (node, evt) |
| node-drag-enter | 拖拽进入某节点时触发 | (draggingNode, dropNode, evt) |
| node-drag-leave | 拖拽离开某节点时触发 | (draggingNode, oldDropNode, evt) |
| node-drag-over | 拖拽经过某节点时触发 | (draggingNode, dropNode, evt) |
| node-drag-end | 拖拽结束时触发 | (draggingNode, dropNode, dropType, evt)(dropNode 可能为 null,dropType 为 before / after / inner / none) |
| node-drop | 拖拽放置完成时触发 | (draggingNode, dropNode, dropType, evt) |
Exposes
| 名称 | 说明 | 参数 |
|---|---|---|
| filter | 过滤所有节点,不匹配的节点被隐藏 | (value) value 会作为 filter-node-method 的首个参数 |
| updateKeyChildren | 为节点设置新数据(需 node-key) | (key, data) |
| getCheckedNodes | 返回当前勾选的节点数据数组 | (leafOnly, includeHalfChecked) 均默认 false;leafOnly=true 仅返回叶子;includeHalfChecked=true 含半选节点 |
| setCheckedNodes | 勾选指定节点(需 node-key) | (nodes, leafOnly) 1. 要勾选的节点数组 2. 是否仅作用于叶子(默认 false) |
| getCheckedKeys | 返回当前勾选的节点 key 数组 | (leafOnly) 默认 false;为 true 时仅返回叶子 |
| setCheckedKeys | 勾选指定 key(需 node-key) | (keys, leafOnly) |
| setChecked | 勾选/取消勾选单个节点 | (keyOrData, checked, deep) 1. 节点 key 或数据 2. 是否勾选 3. 是否递归子节点(自 2.14.0 起无视 check-strictly 生效) |
| getHalfCheckedNodes | 返回半选节点数据数组 | — |
| getHalfCheckedKeys | 返回半选节点 key 数组 | — |
| getCurrentKey | 返回当前高亮节点的 key(无高亮则 null) | — |
| getCurrentNode | 返回当前高亮节点的数据(无高亮则 null) | — |
| setCurrentKey | 按 key 设置高亮节点(需 node-key) | (key, shouldAutoExpandParent=true) 传 null 取消高亮 |
| setCurrentNode | 设置高亮节点(需 node-key) | (node, shouldAutoExpandParent=true) |
| getNode | 按 data 或 key 获取节点 | (data) |
| getNodePath | 返回节点路径(从根到该节点,需 node-key) | (data) |
| remove | 删除节点(需 node-key) | (data) |
| append | 为指定父节点追加子节点 | (data, parentNode) |
| insertBefore | 在指定节点前插入 | (data, refNode) |
| insertAfter | 在指定节点后插入 | (data, refNode) |
Slots
| 插槽名 | 说明 | 类型 |
|---|---|---|
| default | 自定义节点内容 | { node: TreeNode, data: TreeNodeData } |
| empty | 数据为空时的自定义内容 | — |
类型声明
展开声明
ts
type TreeKey = string | number
type TreeNodeData = Record<string, any>
type TreeData = TreeNodeData[]
interface TreeOptionProps {
children?: string
label?: string | ((data: TreeNodeData, node: TreeNode) => string)
disabled?: string | ((data: TreeNodeData, node: TreeNode) => boolean)
isLeaf?: string | ((data: TreeNodeData, node: TreeNode) => boolean)
class?:
| string
| ((
data: TreeNodeData,
node: TreeNode,
) => string | { [key: string]: boolean })
}
// TreeNode(通过 ref 访问的节点对象)部分字段:
type TreeNode = {
canFocus: boolean
checked: boolean
childNodes: TreeNode[]
data: TreeNodeData
expanded: boolean
id: number
indeterminate: boolean
isCurrent: boolean
isEffectivelyChecked: boolean
isLeaf?: boolean
isLeafByUser?: boolean
level: number
loaded: boolean
loading: boolean
parent: TreeNode | null
text: string | null
visible: boolean
// 方法:expand / collapse / setChecked / remove 等
}