vue实现树组件
Vue 树形组件的实现方法
递归组件实现基础树结构
递归组件是 Vue 实现树形结构的核心方式。通过组件调用自身实现无限层级嵌套。
<template>
<ul>
<li v-for="item in treeData" :key="item.id">
{{ item.label }}
<tree-node v-if="item.children" :treeData="item.children"/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeNode',
props: {
treeData: Array
}
}
</script>
数据格式示例:
data() {
return {
treeData: [
{
id: 1,
label: '节点1',
children: [
{ id: 2, label: '子节点1' }
]
}
]
}
}
添加展开/折叠功能
通过添加 isOpen 状态控制子节点的显示隐藏。
<template>
<ul>
<li v-for="item in treeData" :key="item.id">
<span @click="toggle(item)">
{{ item.isOpen ? '▼' : '▶' }} {{ item.label }}
</span>
<tree-node
v-if="item.children && item.isOpen"
:treeData="item.children"
/>
</li>
</ul>
</template>
<script>
export default {
methods: {
toggle(item) {
this.$set(item, 'isOpen', !item.isOpen)
}
}
}
</script>
实现复选框功能
添加复选框并处理父子节点联动逻辑。

<template>
<ul>
<li v-for="item in treeData" :key="item.id">
<input
type="checkbox"
v-model="item.checked"
@change="handleCheckChange(item)"
>
<span @click="toggle(item)">
{{ item.isOpen ? '▼' : '▶' }} {{ item.label }}
</span>
<tree-node
v-if="item.children && item.isOpen"
:treeData="item.children"
@check-change="onChildCheckChange"
/>
</li>
</ul>
</template>
<script>
export default {
methods: {
handleCheckChange(item) {
this.updateChildrenChecked(item, item.checked)
this.$emit('check-change', item)
},
updateChildrenChecked(item, checked) {
if (item.children) {
item.children.forEach(child => {
child.checked = checked
this.updateChildrenChecked(child, checked)
})
}
},
onChildCheckChange(child) {
const allChecked = this.treeData.every(item => item.checked)
const someChecked = this.treeData.some(item => item.checked)
this.$emit('check-change', { ...child, indeterminate: !allChecked && someChecked })
}
}
}
</script>
使用第三方库
对于复杂需求,可以考虑成熟的第三方组件库:
-
Element UI 的树组件:

<el-tree :data="treeData" show-checkbox node-key="id" :props="defaultProps" ></el-tree> -
Vuetify 的树视图:
<v-treeview :items="treeData" selectable return-object ></v-treeview> -
Vue Draggable Tree(支持拖拽):
<vue-draggable-tree :data="treeData" @change="handleChange" />
性能优化建议
对于大型树结构,需要关注渲染性能:
- 使用
v-show替代v-if避免频繁销毁/创建组件 - 添加
:key属性帮助 Vue 高效更新 - 实现虚拟滚动(如使用
vue-virtual-scroller) - 按需加载数据(展开时再加载子节点)
async loadChildren(item) {
if (!item.childrenLoaded) {
const res = await api.getChildren(item.id)
this.$set(item, 'children', res.data)
this.$set(item, 'childrenLoaded', true)
}
}






