vue 实现树状递归
实现树状递归的基本思路
在 Vue 中实现树状递归通常涉及组件递归调用自身,适用于展示层级数据(如文件夹结构、组织架构等)。核心是通过组件内部引用自身,并动态传递数据。
递归组件的定义
创建一个递归组件需要满足两个条件:组件具有 name 属性,并在模板中通过该名称调用自身。
<template>
<div>
<div>{{ node.name }}</div>
<tree-node
v-if="node.children"
v-for="child in node.children"
:node="child"
:key="child.id"
/>
</div>
</template>
<script>
export default {
name: 'TreeNode', // 必须定义 name
props: {
node: Object // 接收父节点数据
}
}
</script>
数据结构的准备
树状递归依赖嵌套数据结构,通常每个节点包含 children 数组表示子节点。示例数据格式:
const treeData = {
id: 1,
name: 'Root',
children: [
{
id: 2,
name: 'Child 1',
children: [{ id: 3, name: 'Grandchild 1' }]
}
]
}
使用动态组件避免循环依赖
若遇到递归组件导入问题,可通过动态组件解决:
<template>
<component
:is="node.children ? 'TreeNode' : 'span'"
:node="node"
/>
</template>
<script>
import { defineAsyncComponent } from 'vue'
export default {
components: {
TreeNode: defineAsyncComponent(() => import('./TreeNode.vue'))
}
}
</script>
性能优化建议
对于大型树结构,可通过以下方式优化:
- 添加
v-if控制子节点渲染,避免初始加载全部节点 - 使用
:key确保节点更新效率 - 实现懒加载,动态获取子节点数据
完整示例代码
<!-- TreeNode.vue -->
<template>
<div class="node">
<div @click="toggle">{{ node.name }}</div>
<div v-if="isOpen && node.children">
<tree-node
v-for="child in node.children"
:key="child.id"
:node="child"
/>
</div>
</div>
</template>
<script>
export default {
name: 'TreeNode',
props: ['node'],
data() {
return {
isOpen: false
}
},
methods: {
toggle() {
this.isOpen = !this.isOpen
}
}
}
</script>
<!-- App.vue -->
<template>
<tree-node :node="treeData" />
</template>
<script>
import TreeNode from './TreeNode.vue'
export default {
components: { TreeNode },
data() {
return {
treeData: {
id: 1,
name: 'Root',
children: [
{
id: 2,
name: 'Child 1',
children: [{ id: 3, name: 'Grandchild 1' }]
}
]
}
}
}
}
</script>





