当前位置:首页 > 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实现密码

vue实现密码

Vue 密码输入组件实现 基础密码输入框实现 使用 Vue 的 v-model 指令绑定数据,并通过 type="password" 设置输入类型为密码: <template> &…

vue实现多选联动

vue实现多选联动

vue实现多选联动的方法 使用v-model绑定数组 在Vue中,可以通过v-model绑定一个数组来实现多选联动。当复选框被选中或取消选中时,数组会自动更新。 <template>…

vue实现路由导航

vue实现路由导航

路由导航的实现方式 在Vue中,路由导航主要通过Vue Router实现。Vue Router是Vue.js官方的路由管理器,用于构建单页面应用(SPA)。 基本路由配置 安装Vue Router…

vue实现网页切换

vue实现网页切换

Vue 实现网页切换的方法 在 Vue 中实现网页切换通常可以通过以下几种方式完成,具体取决于项目需求和路由管理方式。 使用 Vue Router Vue Router 是 Vue.js 官方提供的…

vue实现多级表头

vue实现多级表头

Vue 实现多级表头的方法 使用 el-table 组件 Element UI 的 el-table 组件支持多级表头的实现,通过嵌套 el-table-column 即可完成。 <el-ta…

vue实现打字机

vue实现打字机

Vue实现打字机效果 在Vue中实现打字机效果可以通过动态更新文本内容并添加延迟来实现。以下是几种常见的实现方法: 使用setInterval实现 <template> <d…