vue递归实现树
递归组件实现树形结构
在Vue中通过递归组件实现树形结构是一种常见方式,核心是利用组件调用自身的能力。需要设置name属性以便组件内部递归调用。
<template>
<ul>
<li v-for="item in treeData" :key="item.id">
{{ item.name }}
<tree-node v-if="item.children" :treeData="item.children"/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeNode', // 必须声明name才能递归
props: {
treeData: {
type: Array,
required: true
}
}
}
</script>
数据格式要求
递归组件需要特定格式的树形数据,通常每个节点包含children数组字段表示子节点:

const treeData = [
{
id: 1,
name: '节点1',
children: [
{
id: 2,
name: '子节点1-1',
children: []
}
]
}
]
动态加载优化
对于大型树结构可采用懒加载方式,当展开节点时再加载子数据:

<template>
<ul>
<li v-for="item in treeData" :key="item.id">
<span @click="loadChildren(item)">
{{ item.name }}
</span>
<tree-node
v-if="item.children && item.expanded"
:treeData="item.children"
/>
</li>
</ul>
</template>
<script>
export default {
methods: {
loadChildren(node) {
if (!node.children.length) {
fetchChildren(node.id).then(res => {
node.children = res.data
this.$set(node, 'expanded', true)
})
} else {
node.expanded = !node.expanded
}
}
}
}
</script>
样式与交互增强
通过CSS实现缩进和展开/折叠图标可以提升用户体验:
ul {
padding-left: 20px;
list-style: none;
}
li {
position: relative;
padding: 5px 0;
}
li:before {
content: '▶';
position: absolute;
left: -15px;
}
li.expanded:before {
content: '▼';
}
性能注意事项
递归组件可能引发性能问题,对于超深层级树应考虑:
- 设置
v-if条件阻止未展开节点的渲染 - 使用虚拟滚动技术处理大量节点
- 避免在递归组件中使用复杂的计算属性






