在 Vue 项目中,我们常使用树形结构组件来展示层级数据。本文将介绍如何使用 Element Plus 的 <el-tree>
组件,在 Vue3 中实现以下需求:
-
✅ 只能勾选叶子节点
-
✅ 每次只能选中一个节点(单选)
-
✅ 页面加载时默认选中第一个父节点的第一个子节点
适用于菜单选择、元数据管理、权限勾选等实际业务场景。
🔧 基础结构
先在模板中使用 <el-tree>
组件,开启勾选功能:
<el-tree
ref="treeRef"
class="filter-tree"
:data="treeList"
:props="defaultProps"
default-expand-all
node-key="id"
highlight-current
v-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.id
checkedKeys.value = [firstChildId]
treeRef.value.setCheckedKeys([firstChildId])
treeName.value = firstChild.name
getMetadataList(firstChildId)
}
})
✅ 实现“只能选叶子节点 + 单选”
通过监听 check-change
事件,控制只能勾选叶子节点,并保证是单选:
const handleCheck = (data, checked) => {
const tree = treeRef.value
const isLeaf = !data.children || data.children.length === 0
if (!isLeaf) {
// 如果不是叶子节点,取消勾选
tree.setCheckedKeys([])
return
}
if (checked) {
// 只保留当前选中的一个
tree.setCheckedKeys([data.id])
checkedKeys.value = [data.id]
treeName.value = data.name
getMetadataList(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,可以留言获取!
如果你觉得本文对你有帮助,欢迎点赞 + 收藏 + 关注支持 ❤️