TinyVue Tree树形控件完全指南

TinyVue Tree 树形控件完全指南:层级数据展示的瑞士军刀

本文基于 OpenTiny TinyVue 官方 API 与示例整理,组件包:@opentiny/vue

如果你做过后台管理系统,一定见过这种场景:左侧一棵目录树,右侧一堆表格,中间还夹着权限勾选------Tree 组件就是干这个的。TinyVue 的 Tree 组件功能相当全面,从基础展示到懒加载、拖拽、编辑、右键菜单,基本把树形交互的坑都填平了。


快速上手

Tree 通过 data 属性传入数据源,默认读取每项的 labelchildren 字段:

vue 复制代码
<template>
  <tiny-tree
    :data="data"
    default-expand-all
    @node-click="nodeClick"
  />
</template>

<script setup>
import { ref } from 'vue'
import { TinyTree } from '@opentiny/vue'

const data = ref([
  {
    id: '1',
    label: '数据 1',
    children: [
      { id: '1-1', label: '数据 1-1', children: [{ id: '1-1-1', label: '数据 1-1-1' }] },
      { id: '1-2', label: '数据 1-2' }
    ]
  },
  {
    id: '2',
    label: '数据 2',
    children: [
      { id: '2-1', label: '数据 2-1' },
      { id: '2-2', label: '数据 2-2' }
    ]
  }
])

function nodeClick(data, node, vm) {
  console.log('点击节点:', data.label)
}
</script>

几个常用外观属性:

属性 说明 默认值
show-line 是否显示连接线 false
size 组件尺寸:medium / small -
indent 相邻级水平缩进(px) 18

非标准数据格式

后端返回的字段名不是 label / children?用 props 做字段映射:

vue 复制代码
<tiny-tree
  :data="data"
  :props="{ children: 'subs', label: 'name', disabled: 'disabled', isLeaf: 'isLeaf' }"
/>
  • disabled:控制节点禁用
  • isLeaf:懒加载模式下标记叶子节点,点了不再请求子数据

节点高亮与选中

高亮和查询都依赖 node-key 指定唯一标识:

vue 复制代码
<tiny-tree
  node-key="id"
  :data="data"
  highlight-current
  :current-node-key="'2-1'"
  @current-change="onCurrentChange"
/>

常用实例方法:

js 复制代码
// 查询
treeRef.value.getCurrentNode()
treeRef.value.getCurrentKey()
treeRef.value.getNode('2-1')
treeRef.value.getNodePath('2-1-1')

// 设置高亮
treeRef.value.setCurrentKey('2-1')
treeRef.value.setCurrentNode(nodeData)

实用技巧 :通过 getNode() 拿到的节点对象,可以访问 parentchildNodesnextSibling 等属性,还能调用 expand() / collapse() 控制展开收起------比手动改 data 优雅多了。


展开控制

属性 / 方法 说明
default-expand-all 初始全部展开
default-expanded-keys 初始展开指定 key 数组(需配合 node-key
expand-on-click-node 点击文字是否展开,默认 true;设为 false 则只有点图标才展开
expandAllNodes(true/false) 一键全部展开/收起
accordion 手风琴模式,同时只展开一个同级节点

监听 @node-expand@node-collapse 即可追踪展开状态变化。


多选模式(Checkbox)

开启多选:

vue 复制代码
<tiny-tree
  node-key="id"
  :data="data"
  show-checkbox
  :check-on-click-node="true"
  :default-checked-keys="['2']"
  :expand-on-click-node="false"
/>

严格模式 check-strictly:父子勾选互不影响,适合权限分配等场景。

勾选相关 API:

js 复制代码
// 查询
treeRef.value.getCheckedKeys(leafOnly)
treeRef.value.getCheckedNodes(leafOnly, includeHalfChecked)
treeRef.value.getHalfCheckedKeys()

// 设置
treeRef.value.setCheckedKeys(['1', '2-1'])
treeRef.value.setChecked(nodeOrKey, checked, deep)

事件区别:

  • @check:触发在被点击的节点上,参数为节点 + 整体勾选状态
  • @check-change每个状态变化的节点都会触发,一次勾选可能连发多个

懒加载

大数据量或按需加载子节点时,lazy + load 是标配:

vue 复制代码
<tiny-tree lazy :load="load" @load-data="onLoadData" />
js 复制代码
function load(node, resolve) {
  if (node.level === 0) {
    // 首次加载根节点
    resolve([
      { id: '1', label: '数据 1' },
      { id: '2', label: '数据 2' }
    ])
  } else if (node.data) {
    // 点击后加载子节点
    fetchChildren(node.data.id).then(children => resolve(children))
  }
}

注意:懒加载模式下 data 属性无效,子数据全靠 resolve() 回调返回。props.isLeaf 标记叶子节点后,点击不再触发 load


节点增删改

不用改原始 data,直接调实例方法:

js 复制代码
treeRef.value.insertBefore(newNode, targetKey)  // 前插
treeRef.value.insertAfter(newNode, targetKey)   // 后插
treeRef.value.append(newNode, targetKey)        // 追加为子节点(顶部)
treeRef.value.remove(targetKey, isSaveChildNode) // 删除;true 时子节点上移
treeRef.value.updateKeyChildren(key, children)  // 替换全部子节点

更新子节点又要保留原有子节点?先 getNode() 拿到 children,改完再 updateKeyChildren()


拖拽

vue 复制代码
<tiny-tree
  draggable
  :allow-drag="allowDrag"
  :allow-drop="allowDrop"
  @node-drop="onDrop"
/>
js 复制代码
function allowDrag(node) {
  return !node.data.disabled
}

function allowDrop(srcNode, targetNode, type) {
  // type: 'prev' | 'inner' | 'next'
  return type !== 'inner' // 示例:禁止拖入节点内部
}

拖拽过程还会触发 node-drag-startnode-drag-enternode-drag-overnode-drag-leavenode-drag-end 等事件。频率较高,建议加节流。


编辑模式

适合可维护的目录树场景:

js 复制代码
treeRef.value.openEdit()           // 进入编辑
treeRef.value.addNode(parentNode)  // 添加子节点并进入编辑
treeRef.value.editNode(node)       // 编辑指定节点
treeRef.value.saveNode()           // 保存当前编辑
treeRef.value.saveEdit()           // 保存全部并返回变更数据
treeRef.value.closeEdit()          // 取消编辑

权限控制:

属性 / 方法 作用
add-disabled-keys / setAddDisabledKeys 禁止添加
edit-disabled-keys / setEditDisabledKeys 禁止编辑
delete-disabled-keys / setDeleteDisabledKeys 禁止删除
delete-node-method 自定义删除钩子,返回 false 或 reject 则取消删除

编辑事件:open-editclose-editsave-editadd-nodeedit-nodedelete-node


过滤与平铺视图

搜索过滤:

vue 复制代码
<tiny-tree
  ref="treeRef"
  :data="data"
  node-key="id"
  :filter-node-method="filterNode"
  highlight-query
/>

<!-- 触发过滤 -->
<tiny-input v-model="keyword" @input="treeRef.filter(keyword)" />
js 复制代码
function filterNode(value, data) {
  if (!value) return true
  return data.label.includes(value)
}

view-type="plain" 切换平铺视图,配合 show-auxi 显示上级路径,搜索场景体验更好。


插槽扩展

插槽 用途
default 自定义节点内容
prefix / suffix 节点前后元素
operation 靠右对齐操作区
empty 无数据时的占位
contextmenu 右键菜单(需 show-contextmenu

也可用 render-content 函数属性做 JSX 渲染。


其它实用特性

  • 单选模式show-radio,但官方建议尽量不用,多选用 checkbox 更灵活
  • 右键菜单show-contextmenu + contextmenu 插槽,用 closeMenu() 关闭
  • 键盘导航:默认支持 ↑↓ 移动、←→ 展开收起、Enter/Space 勾选
  • 连接线show-line 让层级关系一目了然

小结

TinyVue Tree 不是「能展示层级就完事」的基础组件,而是一套完整的树形交互方案:

  1. 展示层:连接线、尺寸、缩进、自定义图标/插槽
  2. 交互层:高亮、多选/单选、展开控制、过滤搜索
  3. 数据层:懒加载、增删改、拖拽排序
  4. 编辑层:内置编辑模式 + 细粒度权限

下次做组织架构、菜单权限、文件目录,直接 <tiny-tree> 安排上,别自己用 ul > li 递归写到怀疑人生。


相关链接

相关推荐
Momo__2 小时前
SSR 懒水合四件套 — 99%的人不知道 Vue 3.5 藏了这些水合策略
前端·vue.js·性能优化
qq4356947012 小时前
Vue01
vue.js
rising start2 小时前
七、Vue Router
前端·vue.js·router
Cobyte3 小时前
18.【SolidJS】 采用 template 内容模板元素创建 DOM 元素
前端·javascript·vue.js
小李云雾4 小时前
Pinia:Vue3 全局状态管理从入门到精通
前端·javascript·vue.js
风吹夏回4 小时前
Vue3 + Element Plus 完整使用指南
前端·javascript·vue.js·element
老毛肚14 小时前
jeecgboot vue TS & 模板化 04
前端·javascript·vue.js
卤蛋fg619 小时前
高性能 Vue 甘特图:vxe-gantt 如何秒级渲染万级任务数据
vue.js
逐光老顽童21 小时前
用 Go 实现一个 LLM 路由网关:Thompson Sampling 与自适应故障转移实践
vue.js·go