Vue3 + Element Plus 实现树形结构的“单选 + 只选叶子节点 + 默认选中第一个子节点”
在 Vue 项目中,我们常使用树形结构组件来展示层级数据。本文将介绍如何使用 Element Plus 的 <el-tree>
组件,在 Vue3 中实现以下需求:
-
✅ 只能勾选叶子节点
-
✅ 每次只能选中一个节点(单选)
-
✅ 页面加载时默认选中第一个父节点的第一个子节点
适用于菜单选择、元数据管理、权限勾选等实际业务场景。
🔧 基础结构
先在模板中使用 <el-tree>
组件,开启勾选功能:
<el-treeref="treeRef"class="filter-tree":data="treeList":props="defaultProps"default-expand-allnode-key="id"highlight-currentv-model="checkedKeys":check-strictly="true":filter-node-method="filterNode"show-checkbox@check-change="handleCheck"
/>
说明:
-
show-checkbox
: 开启复选框 -
check-strictly
: 允许父子节点互不关联勾选 -
@check-change
: 自定义处理勾选行为
📦 树结构数据与属性设置
const treeList = ref([{id: 1,name: '父节点 1',children: [{ id: 11, name: '子节点 1-1' },{ id: 12, name: '子节点 1-2' }]},{id: 2,name: '父节点 2',children: [{ id: 21, name: '子节点 2-1' }]}
])const defaultProps = {children: 'children',label: 'name'
}
🚀 默认选中第一个子节点
我们希望在页面加载时,就自动选中第一个父节点的第一个子节点:
onMounted(() => {const firstParent = treeList.value[0]if (firstParent?.children?.length) {const firstChild = firstParent.children[0]const firstChildId = firstChild.idcheckedKeys.value = [firstChildId]treeRef.value.setCheckedKeys([firstChildId])treeName.value = firstChild.namegetMetadataList(firstChildId)}
})
✅ 实现“只能选叶子节点 + 单选”
通过监听 check-change
事件,控制只能勾选叶子节点,并保证是单选:
const handleCheck = (data, checked) => {const tree = treeRef.valueconst isLeaf = !data.children || data.children.length === 0if (!isLeaf) {// 如果不是叶子节点,取消勾选tree.setCheckedKeys([])return}if (checked) {// 只保留当前选中的一个tree.setCheckedKeys([data.id])checkedKeys.value = [data.id]treeName.value = data.namegetMetadataList(data.id)}
}
说明:
-
isLeaf
判断节点是否为叶子节点 -
非叶子节点禁止勾选
-
每次只勾选一个节点,模拟“单选”行为
📡 示例接口调用
function getMetadataList(id) {console.log('请求元数据 for 节点 ID:', id)// 示例:调用接口// axios.get(`/api/metadata/${id}`).then(res => ...)
}
🧩 效果演示
加载后默认选中:
父节点 1✅ 子节点 1-1 ← 默认选中⬜ 子节点 1-2
父节点 2⬜ 子节点 2-1
勾选任何父节点会自动清除;只能勾选一个叶子节点。
🔚 总结
通过本文,我们实现了:
-
🌳 使用 Element Plus 构建树形选择组件
-
🔐 限制为“只能选中叶子节点”
-
🔘 实现“单选”逻辑
-
🚀 支持页面加载默认选中第一个子节点
这种方式在实际业务系统中非常常见,建议封装成通用组件,便于后续复用。
📌 如需完整代码或打包 Demo,可以留言获取!
如果你觉得本文对你有帮助,欢迎点赞 + 收藏 + 关注支持 ❤️