Skip to content

Tree 树 ​

用于展示层级数据,支持展开/收起、选中、级联勾选、点选多选、搜索过滤、懒加载、键盘操作与节点拖拽。

⚠️ 破坏性变更(v2.5):expanded / checked 由「逗号分隔字符串」改为「JSON 字符串数组」。 旧写法 expanded="a,b" / checked="a-1,b" 已失效,请迁移为 expanded='["a","b"]' / checked='["a-1","b"]'。 迁移原因:key 本身含逗号时逗号串会解析错误;JSON 数组与 oas-tree-select 的 expanded/value 形态统一。 若 key 可能含逗号等特殊字符,旧版数据会丢节点,升级后请按数组形态重建属性。

基础用法 ​

层级树

点击展开按钮显示 / 收起子节点,点击节点文本选中该节点;树支持完整键盘操作(↑/↓ 移动焦点、→ 展开、← 收起、Home/End、Space 勾选、Enter 选中)。

触屏适配:展开按钮图标保持 20px,触控(coarse pointer)下命中区自动扩到 44px 触控目标(透明热区外扩),点中率与视觉密度兼顾。

受控展开与选中 ​

初始展开与选中

expanded 为 JSON 字符串数组(如 '["a","b"]'),selected 为选中节点 key。也可组合 default-expand-all(首次全展开,显式 expanded 优先)、auto-expand-parent(外部注入深层 key 时自动补全祖先)、expand-trigger="node"(点击节点即展开/收起)。

勾选(级联) ​

勾选级联(父选全勾、半选回显)

勾选集合(checked 属性,JSON 数组):—

checkable 开启勾选后为级联模型(与 oas-tree-select 语义一致):勾选父级自动勾选其全部可勾选子级;某父级的全部子级被勾选后父级自动收敛为勾选;部分子级勾选时父级复选框显示半选(indeterminate)。

非级联勾选(check-strictly)与默认展开

check-strictly 关闭级联(勾选父级不影响子级);default-expand-all 初始全展开;auto-expand-parent 宿主写入 expanded 属性时自动补全祖先展开(勾选/点选不触发)。

空态(empty 文案与空态插槽)

empty 属性自定义空态文案;也可用 template[slot="empty"] 放富内容。

  • check-strategy:all(默认,父级+子级全进值)/ parent(子级全选时以父级代表,只保留父级)/ child(只保留叶子);
  • check-strictly:父子解耦,勾选互不级联、无半选;
  • 数据字段可加 disableCheckbox: true 禁单个节点勾选(级联跳过);整树禁交互用组件级 disabled 属性。

点选多选 ​

点选多选(multiple,再点取消)

设置 multiple 后 selected 变为 JSON 字符串数组,点击标签在集合中追加 / 移除(再点已选项取消)。勾选(checkable)与点选(multiple/selected)是两套独立模型,可同时启用。

展开行为 ​

手风琴(accordion)+ 树线(tree-lines)+ 点击节点展开

  • accordion:展开某节点时自动收起同层兄弟(手风琴互斥);
  • tree-lines:渲染祖辈缩进引导线(属性名与 oas-tree-select 一致);
  • expand-trigger="node":点击节点文本同时展开/收起(缺省 "toggle" 只点箭头);
  • auto-expand-parent:宿主 setAttribute('expanded', '["深层key"]') 时组件自动补全祖先展开。

搜索过滤 ​

树内过滤(命中保留祖先与子树 + 可选高亮)

filter 为搜索词(属性驱动,搜索框由宿主自配,示例用 oas-input 联动)。命中后保留其全部祖先(路径)与全部后代(命中即含子树),不依赖展开状态;无命中显示空态。filter-highlight 开启时默认 label 文本命中片段包 <mark> 高亮;也可用属性回调 filterNode(label, node) 自定义命中判定(缺省 label 包含关键词,大小写不敏感)。

字段映射 ​

字段别名(field-names)

宿主数据结构不同时用 field-names 映射(JSON 对象,键:key/label/children/disabled/isLeaf/loaded,值对应数据里的字段名),在数据入口归一化一次,与 oas-tree-select 共用同一套字段归一。

禁用状态 ​

节点禁用(disabled / selectable / disableCheckbox)

  • 节点 disabled: true:整行不可交互(点选/展开/勾选);
  • 节点 selectable: false:点选与键盘选中被排除,勾选与展开不受影响;
  • 节点 disableCheckbox: true:复选框禁用且不进级联;
  • 组件级 disabled 属性:整树禁交互(只读展示树)。

命令式方法与滚动 ​

全部展开 / 收起 / 定位

全部展开全部收起滚动到「子节点 58」

命令式方法(数据仍由宿主受控,方法只换算展开集合 / 滚动位置):

  • expandAll() / collapseAll():全部展开 / 全部收起;
  • expand(keys: string[]) / collapse(keys: string[]):展开 / 收起指定 key 集合;
  • scrollTo(key, { expand?: boolean }):滚动定位到节点(默认先展开祖先链;expand: false 时不改展开状态)。

懒加载 ​

懒加载(展开时异步回填子节点)

点击「目录 A」前的展开箭头触发加载

懒加载失败重试(oas-load-error)

点「会失败」的展开箭头看失败事件与重试

设置 lazy 后,无 children 且未标记 isLeaf / loaded 的节点视为「未加载」:点击展开箭头派发 oas-load(detail: { key })并调用 load 属性回调,由宿主回填子节点后重设 data 属性;加载期间展开箭头位置显示 loading 占位(可 template[slot="toggle-loading"] 替换),回填完成后自动展开并收起占位。load 回调返回 Promise 且 reject 时:自动清除加载态、回滚展开、派发 oas-load-error(detail: { key, error }),节点恢复为可再次点击重试。标记 isLeaf: true 的节点不显示展开箭头。

节点拖拽 ​

可拖拽(拖动换序 / 换父)

拖拽节点到目标行上 / 下 / 中部,分别插入其前 / 后 / 子

设置 draggable 后可拖拽节点换序或换父:拖到目标行上 25% 区域插入其前(before)、下 25% 区域插入其后(after)、中部且目标可展开时移入其下(inner;目标不可展开时中部按上下半行取 before/after),拖拽过程有插入线与高亮反馈;松手派发 oas-node-drop(detail: { dragKey, dropKey, position }),由宿主更新数据后重设 data 属性。拖到树空白处视为移入根(dropKey 为空字符串、position: 'inner')。

拖拽全程另有生命周期事件组:oas-node-dragstart(detail: { dragKey })、oas-node-dragover / oas-node-dragleave(detail: { dragKey, dropKey, position },拖到空白处 dropKey 为空、position: 'inner')、oas-node-dragend(detail: { dragKey }),可用于自定义拖拽提示、跨树联动等场景。

落点合法性可用属性回调守卫(拖拽中即拒绝,无插入线反馈):

js
tree.allowDrop = ({ dragKey, dropKey, position }) => dropKey !== 'grp-1' // 不允许拖入该节点
tree.allowDrag = (node) => node.key !== 'item-1' // 该节点不可被拖动

大数据量(虚拟滚动) ​

万级节点虚拟滚动

设置 height 开启虚拟化(搭配 row-height 定高):树复用 oas-virtual-list 只渲染可见窗口内的节点,展开状态保存在 expanded 属性中,滚动与重渲染均不丢失;键盘导航与 scrollTo() 会联动滚动窗口。

自定义节点渲染 ​

自定义节点(图标 + 富文本)

节点内容可用 template[slot="node"] 提供静态骨架([data-node-label] 节点自动绑定节点 label),template[slot="toggle"] 可替换默认展开箭头;每个节点行渲染后派发 oas-node-render(detail: { node, element, level, expanded, selected, checked }),宿主可监听改写 element 为任意图标 / 富文本。示例中任务数徽标即由该事件写入;键盘与 ARIA(treeitem / aria-expanded / aria-level)在自定义渲染下保持不变。

目录模式(文件浏览器) ​

目录模式(文件浏览器样式)

设置 directory 后按文件浏览器风格渲染:有 children(或懒加载下未加载)的节点显示文件夹图标,isLeaf / 无 children 的节点显示文件图标;文件夹按展开 / 收起切换图标,层级缩进与 hover 高亮行沿用行样式。可叠加 tree-lines 显示祖辈引导线。

节点重命名 ​

内联重命名(双击或 F2,Enter 提交 / Esc 取消)

双击「研发团队」或其子节点 label,或选中后按 F2 重命名

设置 can-rename 开启节点重命名:双击节点 label(或选中后按 F2)进入内联编辑态;Enter / 失焦提交、Esc 取消(还原旧值、不派发事件)。编辑态输入框内方向键归输入框,不影响树 roving 键盘导航;节点数据可加 renamable: false 细粒度禁止单个节点重命名。

数据由宿主受控:提交时组件只派发 oas-node-rename(detail: { key, label, oldLabel })不改数据——宿主监听该事件把新 label 写回数据并重设 data 属性后,行内才显示新名字;宿主不更新则保持旧值(避免组件单方面改数据导致不同步)。

展开/收起过渡动画 ​

展开收起过渡(motion 开关对比)

开启动画动画关闭(点击展开箭头为即时切换)

设置 motion 开启展开/收起的高度过渡动画(默认关):展开时新增子行从 0 高平滑生长到自然行高,收起时子行先收缩离场再移除,时长/缓动走 --oas-transition-* token。虚拟滚动模式(设置 height)下展开入场降级为淡入、收起即时切换——虚拟列表行高定值不适合高度动画,避免错位与性能损耗;动画尊重 prefers-reduced-motion(系统减少动效时自动停用)。

展开/收起事件 ​

oas-expand(节点展开/收起)

最近动作:点击展开箭头试试

任意展开/收起交互(展开箭头、expand-trigger="node"、键盘 →/←)都会派发 oas-expand,detail: { key, expanded, node }——node 为该数据节点的快照,宿主可据此联动其他视图。

事件 ​

选中与勾选事件

选中:— · 勾选:—

尺寸五档(size) ​

size 控制整树字号与行内边距,五档:xs / small / medium / large / xl(sm / md / lg 别名等价接受,非法值回落 medium)。medium 为默认档(与不设置一致)。

size 五档对比

整行块级选中区(block-node) ​

block-node 把行渲染为更高的块级命中区:选中/hover 色带本就整行覆盖,开启后行块再加高一档,适合触达密集(触屏、频繁点选)的场景。默认关闭(紧凑行)。

block-node 开关对比

切换 block-nodeblock-node 已开启:行块更高

整树点选开关(selectable) ​

selectable 控制整树行点选(默认开启保持现状);设为 "false" 后点击/键盘不再选中、不派发 oas-select,展开与勾选不受影响。节点数据级的 selectable: false 字段仍可细粒度排除单节点。

selectable 开关

关 selectable开 selectable点一行试试

整树全选(check-all) ​

check-all(配 checkable 生效)在树顶部渲染整树全选项行:全选写入全部可勾选节点,部分勾选时复选框呈半选(indeterminate),再次点选取消全选;disabled / disableCheckbox 节点不参与。文案默认「全选」,可用 check-all-label 覆盖。每次切换派发 oas-check-all(detail: { checked, values })。

check-all 整树全选

勾选顶部「全选」或逐项勾选,观察三态;再点一次取消全选。

API ​

oas-tree ​

属性 ​

属性说明类型默认值
accordion手风琴(同级同时只展开一支)boolean—
auto-expand-parent勾选子节点时自动展开其父级boolean—
block-node整行块级选中/hover 区(行块加高一档)boolean—
can-rename节点重命名总开关:开启后双击节点 label 或按 F2 进入内联编辑,Enter 提交 / Esc 取消 / 失焦提交;提交派发 oas-node-rename(节点数据可加 renamable: false 细粒度禁单个节点)boolean—
check-all顶部整树全选项行(三态 indeterminate;需 checkable)boolean—
check-all-label全选项行文案(缺省复用 i18n 全选)string—
check-strategy勾选导出策略:all(默认)/ parent / child(checkable 级联时生效)stringall
check-strictly勾选父子解联(勾选父级不联动子级)boolean—
checkable是否显示复选框boolean—
checked勾选节点 key 集合(JSON 字符串数组,如 '["a"]';v2.5 前的旧逗号串已废弃,解析失败按空集合回落并告警)string—
data节点数据 [{ key, label, children?, disabled?, isLeaf?, loaded?, renamable? }],JSON 字符串TreeNode[] | string[]
default-expand-all默认展开全部节点(expanded 属性缺席时生效)boolean—
directory目录模式:有 children(或懒加载下未加载)的节点显示文件夹图标,isLeaf / 无 children 的节点显示文件图标,文件夹按展开 / 收起切换图标boolean—
disabled整树禁用(点选/勾选/展开/拖拽全停,浏览保留)boolean—
draggable节点可拖拽换序 / 换父,落点显示插入线 / 高亮,松手派发 oas-node-dropboolean—
empty空态文案(无数据时;无匹配时走 locale 无匹配文案)string—
expand-trigger节点展开触发:toggle(默认,仅箭头)/ node(点节点行展开)stringtoggle
expanded展开节点 key 集合(JSON 字符串数组,如 '["a"]';v2.5 前的旧逗号串已废弃,解析失败按空集合回落并告警)string—
field-names字段别名 JSON(如 {"label":"name","value":"id","children":"subs"};原始数据不拷贝映射,node-render 拿到宿主原对象)string—
filter树内搜索过滤(输入关键词;配 filter-highlight 高亮与 el.filterNode 自定义)string—
filter-highlight搜索命中片段高亮(mark 标记)boolean—
height虚拟滚动视口高度(px);设置后开启大数据量虚拟化渲染string—
lazy懒加载:无 children 且未标记 isLeaf / loaded 的节点,展开时触发加载boolean—
motion展开/收起高度过渡动画(默认关):非虚拟模式行容器 max-height 过渡展开/收起,虚拟滚动模式入场降级为淡入、收起即时;时长/缓动走 --oas-transition-*,prefers-reduced-motion 下停用boolean—
multiple点选多选(Ctrl/⌘ 点击多选;勾选集 selected 为 JSON 数组)boolean—
row-height虚拟化时每行固定高度(px)string32
selectable整树点选开关,"false" 时点击/键盘不选中不派发 oas-select(展开/勾选不受影响)stringtrue
selected选中节点 keystring—
size整树字号与行距五档(xs~xl,别名等价,非法回落 medium)stringmedium
tree-lines树线缩进引导线boolean—

Property(JS property;是否写回 attribute 见各行说明) ​

Property说明类型默认值
load懒加载函数(property 通道,(node) => Promise<children>)(payload: { key: string }) => void | Promise<unknown>—

事件 ​

事件说明
oas-check勾选变化,detail: { key, checked }
oas-check-all全选行切换时派发,detail: { checked, values }
oas-expand节点展开/收起时派发,detail: { key, expanded, node }(node 为数据节点快照)
oas-load懒加载触发,detail: { key };宿主回填 children 后重设 data 属性
oas-load-error懒加载失败时派发,detail: { key, error },error 为错误消息字符串(loading 消失可再点重试)
oas-node-dragend拖拽结束时派发,detail: { dragKey }
oas-node-dragleave拖拽离开目标时派发,detail: { dragKey, dropKey, position }
oas-node-dragover拖拽悬过目标时派发,detail: { dragKey, dropKey, position }(空白处 dropKey 为空、position 为 inner)
oas-node-dragstart拖拽开始时派发,detail: { dragKey }
oas-node-drop节点拖放,detail: { dragKey, dropKey, position },position 为 before / after / inner;dropKey 为空字符串表示移入根
oas-node-rename内联重命名提交(Enter / 失焦),detail: { key, label, oldLabel };数据由宿主受控——组件不改数据模型,宿主监听后更新 data 才生效(不更新则保持旧值;Esc 取消不派发)
oas-node-render每个渲染的节点行派发,detail: { node, element, level, expanded, selected, checked }(element 为节点 label 容器,宿主可改写为图标 / 富文本)
oas-select选中节点,detail: { key, selected }

插槽 ​

名称说明
template[slot="empty"]自定义空态内容
template[slot="node"]节点行静态模板,克隆到每个节点 label 容器;[data-node-label] 节点自动绑定节点 label
template[slot="toggle"]展开按钮静态模板,克隆到每个可展开节点的展开按钮内(替换默认 › 图标)
template[slot="toggle-loading"]懒加载展开中的指示器(替换 spinner)

节点字段说明:isLeaf: true 表示显式叶子(懒加载下不显示展开箭头);loaded: true 表示已加载完成(配合 children 使用,避免重复触发加载);renamable: false 表示该节点不可重命名(配合 can-rename,缺省可重命名)。

基于 MIT OR Apache-2.0 双许可发布