当前位置: 首页 > news >正文

7.5el-tree 组件详解

el-tree 

el-tree 是 Element Plus 提供的树形控件,用于展示具有层级关系的数据,如组织架构、文件目录、分类菜单等。


一、基本用法

<template><el-tree :data="treeData" :props="defaultProps" @node-click="handleNodeClick" />
</template><script setup>
import { ref } from 'vue'// 树形数据
const treeData = ref([{label: '一级 1',children: [{label: '二级 1-1',children: [{ label: '三级 1-1-1' },{ label: '三级 1-1-2' }]}]},{label: '一级 2',children: [{ label: '二级 2-1' },{ label: '二级 2-2' }]}
])// 节点渲染配置
const defaultProps = {children: 'children',label: 'label'
}const handleNodeClick = (data, node, component) => {console.log('节点被点击:', data)
}
</script>

说明

  • data:树的数据源,数组格式。
  • props:配置节点的 label 和 children 字段名。
  • 默认情况下,节点可展开/折叠。

二、核心属性(Props)

属性类型说明默认值
dataarray树的数据源[]
propsobject配置节点的 labelchildrendisabled 等字段{ label: 'label', children: 'children' }
node-keystring每个节点的唯一标识字段名(用于勾选、展开等状态持久化)-
default-expand-allboolean是否默认展开所有节点false
expand-on-click-nodeboolean是否在点击节点时展开/折叠节点true
check-on-click-nodeboolean是否在点击节点时选中节点false
default-expanded-keysstring[]默认展开的节点 key 数组[]
auto-expand-parentboolean展开子节点时是否自动展开父节点true
show-checkboxboolean节点是否可被选择(显示复选框)false
check-strictlyboolean是否严格遵循父子不互相关联false
default-checked-keysstring[]默认勾选的节点 key 数组[]
highlight-currentboolean是否高亮当前选中节点false
draggableboolean是否开启拖拽节点false
allow-dragFunction判断节点能否被拖拽-
allow-dropFunction拖拽时判定目标节点能否被放置-

三、重要事件(Events)

事件名说明回调参数
node-click节点被点击时触发(data, node, component)
node-contextmenu右键节点时触发(event, data, node, component)
check-change节点选中状态变化时触发(data, checked, indeterminate)
check勾选节点时触发(父子联动)(data, checkedStatus)
current-change当前选中节点变化时触发(data, node)
node-expand节点被展开时触发(data, node, component)
node-collapse节点被折叠时触发(data, node, component)
node-drag-start拖拽开始时触发(node, event)
node-drag-end拖拽结束时触发(node, endDropNode, dropType, event)
node-drop拖拽放置时触发(node, dragNode, dropType, event)

四、常用方法(通过 ref 调用)

const treeRef = ref(null)// 获取当前选中节点
treeRef.value.getCurrentKey()// 设置当前选中节点
treeRef.value.setCurrentKey(key)// 获取当前选中节点数据
treeRef.value.getCurrentNode()// 获取被勾选节点(show-checkbox 时)
treeRef.value.getCheckedKeys() // 返回 key 数组
treeRef.value.getCheckedNodes() // 返回节点数据数组// 设置节点勾选
treeRef.value.setCheckedKeys([key1, key2])// 获取半选中节点(父子不联动时)
treeRef.value.getHalfCheckedKeys()
treeRef.value.getHalfCheckedNodes()// 手动展开/折叠节点
treeRef.value.getNode(key).expanded = true

五、高级功能

1. 带复选框的树(可多选)
<el-tree:data="treeData"show-checkboxnode-key="id":default-checked-keys="[2]"@check-change="handleCheckChange"
/>
const handleCheckChange = (data, checked, indeterminate) => {console.log(`${data.label} 选中状态: ${checked}, 半选: ${indeterminate}`)
}

🔍 check-strictly:设为 true 时,父子节点选中状态不互相关联。

2. 异步加载树节点

适用于大数据量或按需加载场景。

<el-tree:data="treeData"node-key="id":props="asyncProps":load="loadNode"lazy
/>
const asyncProps = {children: 'children',label: 'label',isLeaf: 'leaf' // 标记是否为叶子节点
}const loadNode = (node, resolve) => {if (node.level === 0) {return resolve([{ label: '根目录', id: 1 }])}if (node.level > 3) return resolve([])// 模拟异步请求setTimeout(() => {const data = Array.from({ length: 3 }, (_, i) => ({label: `子节点 ${node.data.label}-${i + 1}`,id: Math.random(),leaf: node.level >= 2 // 2层以下为叶子}))resolve(data)}, 500)
}
3. 自定义节点内容

使用 #default 插槽自定义节点渲染。

<el-tree :data="treeData" :props="defaultProps"><template #default="{ node, data }"><span class="custom-tree-node"><span>{{ node.label }}</span><span><el-button size="small" @click="() => append(data)">新增</el-button><el-button size="small" type="danger" @click="() => remove(node, data)">删除</el-button></span></span></template>
</el-tree>
4. 拖拽排序
<el-tree:data="treeData"node-key="id"draggable:allow-drop="allowDrop":allow-drag="allowDrag"@node-drop="handleDrop"
/>
const allowDrop = (draggingNode, dropNode, type) => {// 不允许将父节点拖拽到子节点下if (type === 'inner' && draggingNode.data.children) {return false}return true
}const allowDrag = (draggingNode) => {return draggingNode.data.label.indexOf('不可拖拽') === -1
}const handleDrop = (dragNode, dropNode, dropType, ev) => {ElMessage.success(`拖拽成功: ${dropType}`)
}

六、 完整案例

<script setup>
import { ref, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'// 树引用
const treeRef = ref(null)// 树数据
const treeData = ref([{id: 1,label: '部门A',children: [{ id: 2, label: '小组A1' },{ id: 3, label: '小组A2' }]},{id: 4,label: '部门B',children: [{ id: 5, label: '小组B1' }]}
])// 配置
const defaultProps = {children: 'children',label: 'label'
}// 事件
const handleNodeClick = (data) => {ElMessage.info(`点击了: ${data.label}`)
}const handleCheckChange = (data, checked) => {console.log(`${data.label} 勾选状态: ${checked}`)
}const getCheckedKeys = () => {const keys = treeRef.value.getCheckedKeys()ElMessage.info('已勾选: ' + keys.join(', '))
}const append = (data) => {const newChild = { id: Date.now(), label: '新节点' }if (!data.children) data.children = []data.children.push(newChild)
}const remove = (node, data) => {const parent = node.parentconst children = parent.data.children || parent.dataconst index = children.findIndex(d => d.id === data.id)children.splice(index, 1)
}onMounted(() => {// 可在此处加载异步数据
})
</script><template><div class="p-4"><h3 class="mb-4">组织架构树</h3><el-button size="small" @click="getCheckedKeys" class="mb-4">获取勾选节点</el-button><el-treeref="treeRef":data="treeData":props="defaultProps"node-key="id"show-checkboxdefault-expand-allhighlight-current@node-click="handleNode-click"@check-change="handleCheckChange"><template #default="{ node, data }"><span class="flex items-center"><span>{{ node.label }}</span><span class="ml-2"><el-button type="primary" link size="small" @click="append(data)">新增</el-button><el-button type="danger" link size="small" @click="remove(node, data)">删除</el-button></span></span></template></el-tree></div>
</template><style scoped>
.custom-tree-node {flex: 1;display: flex;align-items: center;justify-content: space-between;font-size: 14px;padding-right: 8px;
}
</style>

✅ 最佳实践建议

  1. 必须设置 node-key:用于状态持久化,否则勾选/展开状态会错乱。
  2. 大数据量使用 lazy 懒加载:避免一次性渲染卡顿。
  3. 合理使用 check-strictly:根据业务决定父子是否联动。
  4. 拖拽功能谨慎使用:需配合后端保存新顺序。
http://www.xdnf.cn/news/1445959.html

相关文章:

  • 创建消息队列,完成信息传输
  • MySQL索引分类
  • 英语四级学习指南
  • A*(Astar)算法详解与应用
  • 电池分选机的自动化解决方案|深圳比斯特
  • SQLAlchemy ORM 入门教程
  • 马斯克砸钱造AI,却败给最low的“让离职员工轻松拷走代码”
  • MyHeyGen-开源版HeyGen,视频翻译工具
  • 平衡车 - 电机调速
  • HI3516CV610-00S 海思HI3516CV610安防高清视频编解码方案提供开发板
  • Nature Machine Intelligence 基于强化学习的磁性微型机器人自主三维位置控制
  • 物联网能源管控平台建设方案
  • 概率质量/密度函数、累计分布函数详解
  • github存储代码(上传更新删除)--实操版
  • 需求调研与分析
  • 最佳红米手机数据擦除软件
  • 场景题:如果一个大型项目,某一个时间所有的CPU的已经被占用了,导致服务不可用,我们开发人员应该如何使服务器尽快恢复正常
  • 2025年家装设计软件推荐:告别选择困难,轻松打造梦想之家
  • C++的内存和数组的申请释放
  • 对数似然比(LLR)
  • C/C++ 中的inline(内联函数关键字)详解
  • 功能持续优化,应用商店新增CRM分类,1Panel v2.0.10版本正式发布
  • VMware Workstation 磁盘空间不足扩容
  • 【论文阅读】InnerGS: Internal Scenes Rendering via Factorized 3D Gaussian Splatting
  • Linux_网络基础
  • C++学习 part1
  • keepalived高可用
  • 基于单片机PWM信号发生器系统Proteus仿真(含全部资料)
  • 2025年最新 unityHub游戏引擎开发2d手机游戏和桌面游戏教程
  • 使用飞算JavaAI快速搭建酒店管理系统