Tree 树形控件
递归渲染的树。支持选中、勾选(级联 / 独立)、默认展开与连接线。
基础用法
src
App.vue
main.ts
components
docs
选中:src-app
vue
<script setup>
import { ref } from 'vue'
const data = [
{
key: 'src',
label: 'src',
children: [
{ key: 'src-app', label: 'App.vue' },
{ key: 'src-main', label: 'main.ts' }
]
}
]
const selected = ref('src-app')
</script>
<template>
<SrTree :data="data" v-model="selected" :default-expanded-keys="['src']" highlight-current />
</template>选中与勾选是两回事
这是树控件最需要分清的一点:
选中(v-model) | 勾选(v-model:checked) | |
|---|---|---|
| 语义 | 「我当前在看哪个」 | 「我挑中了哪几个」 |
| 数量 | 单选 | 多选 |
| 典型场景 | 文件浏览器、目录导航 | 权限分配、批量操作 |
| 视觉 | 整行高亮 | 复选框 |
两套完全独立,可以只用一套,也可以同时用。
src
App.vue
main.ts
components
Button
Input
docs
README.md
指南.md
已勾选:(无)
vue
<SrTree :data="data" v-model:checked="checked" checkable :default-expand-all="true" />勾选策略
src
App.vue
main.ts
components
Button
Input
docs
README.md
指南.md
cascade:勾父项会连带勾选全部子项
src
App.vue
main.ts
components
Button
Input
docs
README.md
指南.md
independent:各项互不影响,适合「父级只是分组」的场景
vue
<SrTree checkable check-strategy="cascade" />
<SrTree checkable check-strategy="independent" />| 策略 | 行为 | 适用 |
|---|---|---|
cascade | 勾父选全子,子项部分选中时父项半选 | 权限树(父权限包含子权限) |
independent | 各项完全独立 | 分类筛选(选了「前端」不代表要选「Vue」) |
默认展开
src
App.vue
main.ts
components
Button
Input
docs
展开指定的两级
vue
<SrTree :data="data" :default-expanded-keys="['src', 'src-components']" />
<SrTree :data="data" :default-expand-all="true" />历史缺陷:defaultExpandedKeys 曾完全失效
早期版本在取值时把属性名写成了 defaultExpandKeys(少一个 ed), 而 prop 定义与另一处的判断用的都是正确名字。
后果是 new Set(undefined) 得到空集合,看起来一切正常、 不报任何错,只是「默认展开」这个功能完全不起作用。
现已修复。这类「拼错一个字母、功能静默失效」的问题, 只有类型检查能稳定抓到。
连接线与缩进
src
App.vue
main.ts
components
Button
Input
docs
README.md
指南.md
src
App.vue
main.ts
components
Button
Input
docs
README.md
指南.md
indent="12":更紧凑的层级缩进
vue
<SrTree :data="data" show-line />
<SrTree :data="data" :indent="12" />节点数据
| 字段 | 类型 | 说明 |
|---|---|---|
key | string | number | 必填,须在整棵树内唯一 |
label | string | 显示文本 |
children | SrTreeNode[] | 子节点 |
disabled | boolean | 是否禁用(会向下继承到所有子节点) |
isLeaf | boolean | 强制标记为叶子节点 |
isLeaf 用于异步加载场景:子节点还没返回,但不该显示展开箭头时显式传 true。 否则用户会点开一个空目录。
禁用会向下继承
父节点禁用时,其所有子节点也一并不可选。 这符合权限树的直觉——没有父权限,子权限也无从谈起。 若只想禁用单个节点,把它移出该父节点、或用 independent 策略。
Props
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
data | SrTreeNode[] | [] | 树数据 |
modelValue | string | number | null | null | 选中的节点 key |
checked | (string | number)[] | [] | 勾选的节点 key |
checkable | boolean | false | 是否显示复选框 |
checkStrategy | 'cascade' | 'independent' | 'cascade' | 勾选联动策略 |
highlightCurrent | boolean | false | 是否高亮选中行 |
defaultExpandedKeys | (string | number)[] | [] | 默认展开的节点 |
defaultExpandAll | boolean | false | 是否默认展开全部 |
showLine | boolean | false | 是否显示层级连接线 |
indent | number | 18 | 每层缩进(px) |
emptyText | string | — | 空态文案 |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
update:modelValue | 节点 key | 选中项变化 |
update:checked | 节点 key 数组 | 勾选项变化 |
node-click | (node) | 点击节点 |
插槽
| 名称 | 说明 |
|---|---|
label-{key} | 自定义某个 key 的节点显示 |
无障碍
- 使用
role="tree"/role="treeitem",并暴露aria-expanded - 方向键导航:↑↓ 移动、→ 展开、← 收起——这是树控件的标准交互
- 复选框带
aria-checked="mixed"表示半选状态,读屏软件能正确播报