当前位置:首页 > 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形式,每个节点包含:

vue 递归实现树

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

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

性能优化建议

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

vue 递归实现树

  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优秀实现

Vue.js 优秀实现方法 响应式数据管理 使用 Vue 的 ref 和 reactive 处理基础类型和对象类型数据,结合 computed 计算属性优化渲染性能。对于复杂状态,推荐 Pinia 替…

vue实现积分

vue实现积分

Vue 实现积分功能 在 Vue 中实现积分功能通常涉及前端展示、交互逻辑以及与后端 API 的通信。以下是常见的实现方法和步骤: 积分展示组件 创建一个积分展示组件,用于显示当前用户的积分。可以使…

vue实现复选

vue实现复选

Vue 实现复选框 在 Vue 中实现复选框可以通过 v-model 指令绑定数据,同时结合 input 元素的 type="checkbox" 属性来实现。以下是几种常见的实现方式: 单个复选框…

vue实现试卷

vue实现试卷

Vue实现试卷系统的基本思路 使用Vue.js构建试卷系统需要结合组件化开发、状态管理和后端数据交互。核心功能包括题目展示、答题逻辑、计时器和提交答案。 核心功能模块划分 试卷组件结构 试卷容器组…

vue滚动实现

vue滚动实现

Vue 滚动实现方法 使用原生滚动 在 Vue 中可以通过 ref 获取 DOM 元素,调用原生滚动方法实现滚动效果。适用于简单场景。 <template> <div ref=…

vue 动画实现

vue 动画实现

Vue 动画实现方式 Vue 提供了多种方式实现动画效果,主要分为内置组件和第三方库集成。 使用 Vue 内置过渡组件 Vue 的 <transition> 和 <transiti…