当前位置:首页 > VUE

vue 递归实现树

2026-01-08 17:09:28VUE

递归组件实现树形结构

在Vue中可以通过递归组件实现树形结构的渲染,核心思路是组件内部调用自身。以下是一个完整的实现示例:

<template>
  <div class="tree">
    <tree-node :node="treeData" @on-select="handleSelect"></tree-node>
  </div>
</template>

<script>
import TreeNode from './TreeNode.vue'

export default {
  components: { TreeNode },
  data() {
    return {
      treeData: {
        id: 1,
        label: 'Root',
        children: [
          {
            id: 2,
            label: 'Child 1',
            children: [
              { id: 3, label: 'Grandchild 1' },
              { id: 4, label: 'Grandchild 2' }
            ]
          },
          { id: 5, label: 'Child 2' }
        ]
      }
    }
  },
  methods: {
    handleSelect(node) {
      console.log('Selected node:', node)
    }
  }
}
</script>

TreeNode组件实现

<template>
  <div class="node">
    <div @click="toggle" :class="{ 'has-children': hasChildren }">
      {{ node.label }}
    </div>
    <div v-show="isOpen" v-if="hasChildren" class="children">
      <tree-node
        v-for="child in node.children"
        :key="child.id"
        :node="child"
        @on-select="$emit('on-select', $event)"
      ></tree-node>
    </div>
  </div>
</template>

<script>
export default {
  name: 'TreeNode',
  props: {
    node: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      isOpen: false
    }
  },
  computed: {
    hasChildren() {
      return this.node.children && this.node.children.length
    }
  },
  methods: {
    toggle() {
      if (this.hasChildren) {
        this.isOpen = !this.isOpen
      }
      this.$emit('on-select', this.node)
    }
  }
}
</script>

<style>
.node {
  margin-left: 20px;
  cursor: pointer;
}
.has-children {
  font-weight: bold;
}
.children {
  margin-left: 15px;
}
</style>

关键实现要点

递归组件的核心是在组件内部通过name属性注册自身,然后在模板中直接使用。必须设置name属性才能实现递归调用。

数据结构通常采用嵌套的children形式,每个节点包含:

  • id: 唯一标识
  • label: 显示文本
  • children: 子节点数组(可选)

通过v-show控制子节点的展开/折叠状态,计算属性hasChildren判断当前节点是否有子节点。

性能优化建议

对于大型树结构,可以采用虚拟滚动优化:

  1. 计算可见区域内的节点
  2. 只渲染可见部分节点
  3. 滚动时动态更新渲染节点
// 虚拟滚动示例
const visibleNodes = computed(() => {
  return allNodes.value.slice(
    startIndex.value,
    Math.min(startIndex.value + visibleCount.value, allNodes.value.length)
  )
})

动态加载实现

当树节点数据量很大时,可以按需加载子节点:

methods: {
  async loadChildren(node) {
    if (!node.childrenLoaded && !node.children) {
      const res = await api.getChildren(node.id)
      this.$set(node, 'children', res.data)
      this.$set(node, 'childrenLoaded', true)
    }
    this.isOpen = !this.isOpen
  }
}

注意事项

递归组件需要合理控制递归深度,过深的嵌套可能导致堆栈溢出。建议对树形数据做扁平化处理时设置最大深度限制。

组件样式需要注意层级缩进,通过margin-left实现视觉上的树形层次感。交互方面建议添加展开/折叠动画提升用户体验。

vue 递归实现树

标签: 递归vue
分享给朋友:

相关文章

vue实现tab标签

vue实现tab标签

Vue 实现 Tab 标签的方法 使用动态组件和 v-for 渲染标签 通过 v-for 循环生成标签页标题,结合 v-bind:class 动态切换激活状态。使用 v-show 或动态组件 <…

vue前端分页怎么实现

vue前端分页怎么实现

前端分页实现方法 在Vue中实现前端分页通常涉及数据分割和页面控制逻辑。以下是常见的实现方式: 使用计算属性分页 通过计算属性对数据进行切片处理: computed: { paginatedD…

vue插槽实现

vue插槽实现

插槽的基本概念 Vue插槽(Slot)是一种内容分发机制,允许父组件向子组件传递模板片段,子组件通过<slot>标签定义接收位置。插槽的核心作用是增强组件的灵活性和复用性。 默认插槽…

vue el 实现

vue el 实现

Vue 中使用 Element UI (el) 的实现方法 Element UI 是一个基于 Vue 的组件库,提供丰富的 UI 组件,常用于快速构建企业级中后台产品。以下介绍 Vue 项目中集成和使…

vue实现模块

vue实现模块

Vue 实现模块化的方法 Vue 支持多种模块化开发方式,可以根据项目需求选择适合的方案。 使用单文件组件(SFC) 单文件组件是 Vue 最常用的模块化方式,将模板、脚本和样式封装在一个 .vu…

vue实现picker

vue实现picker

Vue 实现 Picker 组件的方法 在 Vue 中实现 Picker 组件可以通过多种方式完成,以下是几种常见的实现方法: 使用原生 HTML 和 CSS 实现 通过 Vue 的模板和样式绑定…