vue 树形checkbox实现
Vue 树形 Checkbox 实现方法
使用递归组件实现树形结构
创建递归组件 TreeCheckbox.vue,通过 v-for 循环子节点并递归调用自身。每个节点包含 checkbox 和展开/折叠图标。
<template>
<div class="tree-node">
<div class="node-content">
<input
type="checkbox"
v-model="node.checked"
@change="handleCheckChange(node)"
/>
<span @click="toggleExpand(node)">{{ node.label }}</span>
</div>
<div class="children" v-show="node.expanded">
<TreeCheckbox
v-for="child in node.children"
:key="child.id"
:node="child"
@check-change="handleChildCheckChange"
/>
</div>
</div>
</template>
<script>
export default {
name: 'TreeCheckbox',
props: {
node: Object
},
methods: {
toggleExpand(node) {
node.expanded = !node.expanded
},
handleCheckChange(node) {
this.updateChildChecked(node, node.checked)
this.$emit('check-change', node)
},
handleChildCheckChange(childNode) {
this.updateParentChecked(this.node)
},
updateChildChecked(node, checked) {
if (node.children) {
node.children.forEach(child => {
child.checked = checked
this.updateChildChecked(child, checked)
})
}
},
updateParentChecked(node) {
if (!node.children) return
const allChecked = node.children.every(child => child.checked)
const someChecked = node.children.some(child => child.checked)
node.checked = allChecked
node.indeterminate = !allChecked && someChecked
}
}
}
</script>
数据结构和状态管理
树形数据应包含必要字段如 id, label, children,以及状态字段 checked, expanded, indeterminate。
const treeData = {
id: 1,
label: 'Root',
expanded: true,
checked: false,
indeterminate: false,
children: [
{
id: 2,
label: 'Child 1',
checked: false,
children: [...]
},
// 更多子节点...
]
}
样式设计
添加基础样式使树形结构清晰可见,包含缩进、复选框对齐和状态指示。
.tree-node {
margin-left: 20px;
}
.node-content {
display: flex;
align-items: center;
padding: 5px 0;
}
.children {
margin-left: 15px;
}
input[type="checkbox"] {
margin-right: 8px;
}
全选/反选功能实现
在父组件中添加控制全选状态的逻辑。
methods: {
selectAll(checked) {
this.updateAllChecked(this.treeData, checked)
},
updateAllChecked(node, checked) {
node.checked = checked
node.indeterminate = false
if (node.children) {
node.children.forEach(child => {
this.updateAllChecked(child, checked)
})
}
}
}
获取选中节点
提供方法获取所有被选中的节点 ID,便于后续处理。
methods: {
getCheckedNodes() {
const checkedNodes = []
this.collectCheckedNodes(this.treeData, checkedNodes)
return checkedNodes
},
collectCheckedNodes(node, result) {
if (node.checked) {
result.push(node.id)
}
if (node.children) {
node.children.forEach(child => {
this.collectCheckedNodes(child, result)
})
}
}
}
使用第三方库(可选)
对于复杂需求,可以考虑使用现成的树形组件库:
element-ui的el-tree组件vuetify的v-treeview组件- 专门处理树的库如
vue-treeselect
这些库提供了更完善的功能如懒加载、搜索过滤、拖拽排序等高级特性。







