Skip to content

TreeSelect 树形选择器 ​

树形结构选择,支持父子级联多选、搜索过滤、懒加载与标签化回显。

单选 ​

单选

点击节点即选中并关闭下拉,支持展开 / 收起子级。键盘:Tab 聚焦、Enter/Space/↑/↓ 展开、↑/↓ 移动高亮、Enter/Space 选中、→/← 展开收起、Esc 关闭。

多选(父子联动 + 标签回显) ​

多选(multiple)

多选时选中父级会级联选中全部子级,再次点击取消;父级节点呈「全选 / 半选」态。选中项以标签(chip)回显在触发器内:点击标签上的 × 可单个移除;触发器聚焦时按 Backspace 删除末尾一项。

视觉变更说明:v2.4 起多选回显从「文本拼接 + 等N项」改为标签形态(支持单个移除的通用形态),属于破坏性视觉变更;如需折叠展示请搭配 max-tag-count。

搜索过滤(filterable) ​

搜索过滤(filterable)

设置 filterable 后面板顶部出现独立搜索框:命中节点与其祖先(路径上下文)、全部后代一并显示(宽松匹配);无匹配时显示空态。搜索框内 ↑/↓ 移动高亮(落在首个命中节点)、Enter 选中、Esc 关闭面板并还焦触发器。选中后默认清空搜索词,reserve-keyword 可保留。输入时派发 oas-search(detail.value 为关键词,可配合 loading 做远程搜索)。自定义匹配逻辑:el.filter = (label, option) => boolean。

搜索输入受控(input-value) ​

input-value(受控搜索词)

input-value 让搜索词可控:属性在场即搜索框的真相源(预设/外部更新会同步进搜索框并重过滤);用户输入写回属性并派发 oas-input-value-change(detail: { value }),宿主可监听事件也可直接读属性。

父子解联(check-strictly) ​

父子解联(check-strictly)

级联:值 = —

解联:值 = —

multiple 默认父子级联(勾选父级即勾选全部子级)。设置 check-strictly 后勾选互不级联、无半选态,value 即勾选集合本身(check-strategy 此时不再生效)——覆盖「任意层级独立多选」场景。

勾选策略(check-strategy) ​

check-strategy 控制多选时写入 value 的节点集合:all(默认)父级与子级全部进入值;parent 只保留父级(子级全选时以父级为代表);child 只保留叶子节点。三种策略共用同一套级联勾选逻辑,仅对外值不同:

勾选策略对比(all / parent / child)

all:值 = —

parent:值 = —

child:值 = —

勾选「前端」后三个策略的 value 分别为:all → ["fe","framework","vue","react","css"],parent → ["fe"],child → ["vue","react","css"](顺序随 demo 数据中「框架」子节点的声明顺序)。parent 策略下逐个勾选叶子,待某父级子节点全选后,值自动收敛为该父级。

懒加载(lazy / load) ​

懒加载(lazy + load)

设置 lazy 后,无 children 且未标记 isLeaf / loaded 的节点视为「未加载」:展开时显示 spinner、派发 oas-load(detail.value)并调用 el.load({ value });宿主把子节点合入数据后重新设置 options,spinner 随之消失。显式叶子用 isLeaf: true 标记。右侧示例:预设了尚未加载的值 js,通过 cache-data(JSON:[{ value, label }])让回显不显示原始 value。

路径回显(show-path) ​

路径回显(show-path + separator)

show-path 让选中项按「根 → 自身」的完整路径回显(如 前端 / 框架 / Vue),用于两个子树存在同名节点时的消歧;separator 自定义分隔符(默认 " / ")。

多选标签管理(max-tag-count / max) ​

标签折叠与多选上限

值 = —

值 = —

max-tag-count 控制触发器内最多显示的标签数,超出折叠为 +N(悬浮 title 列出隐藏项);max 限制可选节点数(按勾选数量计),达到上限后未勾选节点呈禁用态、已勾选仍可取消。

可清空与前后缀(clearable / prefix / suffix) ​

clearable + prefix / suffix

clearable 有值时触发器显示清空按钮(点击清空并派发 oas-clear);prefix-text / suffix-text 为触发器内前后缀文本,也可用 template[slot="prefix"] / [slot="suffix"] 插槽自定义内容。prefix / suffix 为兼容别名(规范名 prefix-text / suffix-text),attribute 与 property(React / Vue 绑定)两条通道均可用。

自定义后缀图标(suffix-icon 插槽) ​

suffix-icon(替换默认箭头)

template[slot="suffix-icon"] 替换触发器默认下拉箭头(展开时随容器旋转)。

值携带标签(label-in-value) ​

label-in-value(value 携 { value, label } 对象)

设置 label-in-value 后,value 属性与 oas-change 的 detail.value 携带 { value, label } 对象(单选为对象、多选为对象数组),表单提交需要「值 + 标签」时宿主不再反查;树外预设值可用对象里的 label 直接回显。FormData 提交值保持纯字符串不受影响。

尺寸与校验态(size / status) ​

size 三档 + status 校验态

size:small / medium(默认)/ large,高度与字号对齐全局尺寸 token;status:error / warning / success 校验态描边(aria-invalid 宿主属性仍然兼容,等同 error)。

字段别名(field-names) ​

字段别名(field-names)

后端数据字段名不一致时,用 field-names(JSON)声明 label / value / children / disabled 到原始字段的映射,无需在宿主侧转换整棵树。

受控开合(open) ​

受控开合(open + oas-open-change)

切换 open

open 属性存在即受控(值为 false 表示受控关闭):内部点击不再直接改开合,只派发 oas-open-change(detail.open),由宿主回写 open 属性决定;未设置 open 时为非受控(开合同样派发该事件,便于宿主感知首开做数据预载)。

展开行为(default-expand-all / tree-lines / expand-trigger) ​

默认全展 / 树线 / 点击节点展开

default-expand-all 首次打开默认展开全部节点(显式设置 expanded 属性时以 expanded 为准);tree-lines 显示层级缩进引导线;expand-trigger="node" 时点击父级标签在选中之外同时展开(默认 toggle 仅箭头展开)。

自定义节点渲染 ​

oas-node-render 事件

template[slot=node] 模板

两个通道:监听 oas-node-render(detail: { node, element, level, expanded, selected, checked })在事件里改写 element;或用 template[slot="node"] 提供静态骨架、[data-node-label] 自动绑定节点 label(与 oas-tree 通道一致)。树的 ARIA(treeitem / aria-level)不受自定义渲染影响。

面板头尾插槽 + loading 遮罩

切换 loading

template[slot="header"] / [slot="footer"] 在面板顶部 / 底部插入任意内容;loading 显示面板加载遮罩(常与远程搜索、懒加载配合);空态文案可用 empty 属性或 template[slot="empty"] 插槽自定义(默认走内置多语言文案)。

扁平数据(宿主工具函数) ​

后端平表 {id, pId} → 树

组件不提供扁平数据属性——后端平表在宿主侧一行 reduce 即可转树(零摩擦),本页示例的数据转换函数见下方脚本:

预设值 ​

预设值(value)

受控展开(expanded) ​

expanded 为 JSON 数组,声明展开节点的 value 集合(受控通道):外部修改属性即时反映到下拉树。以下预设展开「前端 → 框架」,并用按钮外部驱动:

受控展开(expanded)

全部展开全部收起

预设 expanded='["fe","framework"]' 使首次展开下拉时「前端」「框架」已展开;点击「全部展开」外部写入 expanded='["fe","framework","be"]',全部收起写入 '[]',下拉打开时即时重渲染。

大数据量(虚拟滚动) ​

万级节点虚拟滚动

全部展开全部收起

设置 virtual 开启虚拟滚动(搭配 height 视口高度、item-height 行高):下拉复用 oas-virtual-list 只渲染可见窗口,10100 个节点(100 部门 × 100 成员)滚动流畅;键盘 ↑/↓ 移动高亮、Enter 勾选、→/← 展开收起,aria-activedescendant 随窗口滚动保持有效。filterable 与虚拟滚动可叠加(过滤结果进窗口渲染)。数据由脚本注入(options 属性通道),展开集合受 expanded 属性控制,点击「全部展开」外部写入全量节点集合。

弹层定位(滚动容器) ​

滚动容器内使用

overflow 容器内的树选择器:

↓ 向下滚动:弹层以 fixed 定位锚定触发器,不随容器裁剪;视口空间不足时自动向上翻转。

下拉面板使用 fixed 定位 + 视口计算锚定触发器下方(宽度对齐触发器,空间不足自动翻转),在模态、滚动容器内不会被 overflow 裁剪。定位微调可走 ::part(dropdown)。

禁用 ​

禁用

空态 ​

无数据

自定义空态(empty)+ 保留搜索词(reserve-keyword)

事件 ​

变化事件

监听 oas-change,detail.value 单选为字符串、多选为数组;detail.labels 为按值顺序的回显 label 数组(show-path 时为路径),宿主需要「值 + label」时从这里取,无需对象值绑定。其余事件:oas-clear(清空,detail.value 为清空前的值)、oas-search(搜索输入)、oas-load(懒加载)、oas-open-change(开合)、oas-node-render(节点渲染)。

移动形态(底部抽屉) ​

触屏(coarse pointer)或窄视口(<768px)下,面板自动改由 oas-bottom-sheet 底部抽屉承载:贴视口底升起 + 遮罩 + 拖拽把手下滑关闭(点遮罩 / Esc 同样收起),底部避让安全区;搜索框 + 树面板在抽屉内容区内滚动;PC 形态保持原有浮层下拉不变。

required 必填 ​

required 必填(原生校验链)

required 驱动原生校验链(form-associated):未填时 checkValidity() 为 false(valueMissing),原生表单提交被阻止;填写后自动恢复 :valid。

程序性读/写当前值走公开 value property:el.value 读取——单选为选中值字符串(无选中为空串),多选为选中值字符串数组(label-in-value 形态提升为纯值,与 FormData 提交口径一致);el.value = x 写入——写受控 value 属性并回显 label/chips(多选传数组自动 JSON 序列化,label-in-value 保持对象契约形态,空值移除属性),不派发事件。

API ​

oas-tree-select ​

属性 ​

属性说明类型默认值
cache-data未知值回显兜底缓存(JSON),value 无匹配时按缓存出 labelstring[]
check-strategy多选勾选策略:all(默认)父级与子级全部进入值;parent 只保留父级(子级全选时以父级为代表);child 只保留叶子节点stringall
check-strictly多选父子勾选解联(勾选父级不联动子级)boolean—
clearable可清空(派发 oas-clear)boolean—
default-expand-all默认展开全部节点(expanded 属性缺席时生效,首次内部切换后冻结)boolean—
disabled禁用boolean—
empty空态文案/内容自定义string—
expand-trigger节点展开触发:toggle(默认,仅箭头)/ node(点节点行展开)stringtoggle
expanded展开节点的 value 集合(JSON 数组,受控)string—
field-names字段别名 JSON(如 {"label":"name","value":"id","children":"subs"};原始 option 不拷贝映射,node-render 拿到宿主原对象)string—
filterable可搜索(面板顶部独立搜索框)boolean—
height虚拟滚动视口高度(px);与 virtual 搭配生效string288
input-value搜索词受控源(输入写回并派发 oas-input-value-change)string—
item-height虚拟滚动每行固定高度(px)string36
label-in-valuevalue 与 oas-change detail 携 { value, label } 对象(FormData 仍提交纯值)boolean—
lazy懒加载(配 el.load 函数 property,节点含 isLeaf 标记)boolean—
loading面板加载态(懒加载/远程搜索时)boolean—
max多选上限(按勾选集合计)string—
max-tag-count多选标签按数量折叠 +N(带 title 列隐藏项)number—
multiple多选 + 父子级联boolean—
name表单字段名(原生 FormData 提交的 key;多选时作为同名多条 entry 的 key;无 name 浏览器自动不提交)string—
open受控开合(存在即受控;"false"=受控关),翻转派 oas-open-change;移动形态(触屏/窄视口 <768px)下展开态由 oas-bottom-sheet 底部抽屉承载(下滑/遮罩/Esc 收起),PC 为浮层下拉string—
options树形选项,JSON 数组,支持 children / disabledTreeOption[] | string[]
placeholder占位提示——
prefix-text触发器前缀内容(slot="prefix" 可分发任意内容)string—
required必填标记(驱动原生校验链 valueMissing;不透传内层控件)boolean—
reserve-keyword选中节点后保留搜索关键词(默认清空)boolean—
separator路径分隔符(默认 /,配 show-path)string/
show-path回显完整路径(初始回显与多选 labels 走路径)boolean—
size尺寸档位 small / medium(默认)/ largestringmedium
status校验态:error / warning / successstring—
suffix-text触发器后缀内容(slot="suffix" 同上)string—
tree-lines树线缩进引导线boolean—
value选中值(多选为 JSON 数组)string | string[] | null—
virtual开启虚拟滚动:大数据量下拉仅渲染可见窗口(复用 oas-virtual-list),键盘/ARIA 保持boolean—

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

Property说明类型默认值
value当前值:单选为值;多选为值数组string | string[] | null—

事件 ​

事件说明
oas-change选择变化,detail: { value }
oas-clear清空时派发,detail 为清空前的值
oas-input-value-change搜索词变化时派发,detail: { value }
oas-load懒加载节点展开加载时派发,detail: { value }
oas-node-render节点渲染时派发(自定义节点渲染通道),detail: { node, element, level, expanded, selected, checked }
oas-open-change开合状态翻转,detail: { open }
oas-search搜索输入,detail: { value }

插槽 ​

名称说明
template[slot="empty"]自定义空态内容
template[slot="node"]自定义节点模板([data-node-label] 绑定标签)
template[slot="suffix-icon"]自定义触发器后缀图标(替换默认箭头)

CSS 变量 ​

CSS 变量默认值
--oas-glass-blurnone
--oas-glass-ringtransparent

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