Skip to content

Tree 树形控件

递归渲染的树。支持选中、勾选(级联 / 独立)、默认展开与连接线。

基础用法

src
App.vue
main.ts

选中: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

展开指定的两级

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" />

节点数据

字段类型说明
keystring | number必填,须在整棵树内唯一
labelstring显示文本
childrenSrTreeNode[]子节点
disabledboolean是否禁用(会向下继承到所有子节点
isLeafboolean强制标记为叶子节点

isLeaf 用于异步加载场景:子节点还没返回,但不该显示展开箭头时显式传 true。 否则用户会点开一个空目录。

禁用会向下继承

父节点禁用时,其所有子节点也一并不可选。 这符合权限树的直觉——没有父权限,子权限也无从谈起。 若只想禁用单个节点,把它移出该父节点、或用 independent 策略。

Props

名称类型默认值说明
dataSrTreeNode[][]树数据
modelValuestring | number | nullnull选中的节点 key
checked(string | number)[][]勾选的节点 key
checkablebooleanfalse是否显示复选框
checkStrategy'cascade' | 'independent''cascade'勾选联动策略
highlightCurrentbooleanfalse是否高亮选中行
defaultExpandedKeys(string | number)[][]默认展开的节点
defaultExpandAllbooleanfalse是否默认展开全部
showLinebooleanfalse是否显示层级连接线
indentnumber18每层缩进(px)
emptyTextstring空态文案

事件

事件参数说明
update:modelValue节点 key选中项变化
update:checked节点 key 数组勾选项变化
node-click(node)点击节点

插槽

名称说明
label-{key}自定义某个 key 的节点显示

无障碍

  • 使用 role="tree" / role="treeitem",并暴露 aria-expanded
  • 方向键导航:↑↓ 移动、→ 展开、← 收起——这是树控件的标准交互
  • 复选框带 aria-checked="mixed" 表示半选状态,读屏软件能正确播报

自用组件库 · 源码分发 · 不发布 npm