当前位置:首页 > VUE

vue实现树形菜单组件

2026-01-20 23:30:10VUE

vue实现树形菜单组件

数据准备

树形菜单需要递归结构的数据,通常包含id、label、children等字段。例如:

const treeData = [
  {
    id: 1,
    label: '一级菜单',
    children: [
      {
        id: 2,
        label: '二级菜单',
        children: []
      }
    ]
  }
]

递归组件实现

创建TreeItem.vue作为递归组件:

<template>
  <li>
    <div @click="toggle">
      {{ node.label }}
      <span v-if="hasChildren">{{ isOpen ? '-' : '+' }}</span>
    </div>
    <ul v-show="isOpen" v-if="hasChildren">
      <tree-item 
        v-for="child in node.children" 
        :key="child.id" 
        :node="child"
      />
    </ul>
  </li>
</template>

<script>
export default {
  name: 'TreeItem',
  props: {
    node: Object
  },
  data() {
    return {
      isOpen: false
    }
  },
  computed: {
    hasChildren() {
      return this.node.children && this.node.children.length
    }
  },
  methods: {
    toggle() {
      if (this.hasChildren) {
        this.isOpen = !this.isOpen
      }
    }
  }
}
</script>

主组件封装

创建TreeMenu.vue作为主组件:

<template>
  <div class="tree-menu">
    <ul>
      <tree-item 
        v-for="node in treeData" 
        :key="node.id" 
        :node="node"
      />
    </ul>
  </div>
</template>

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

export default {
  components: { TreeItem },
  props: {
    treeData: {
      type: Array,
      required: true
    }
  }
}
</script>

<style>
.tree-menu ul {
  list-style: none;
  padding-left: 20px;
}
.tree-menu li {
  cursor: pointer;
  user-select: none;
}
</style>

功能扩展

添加复选框支持,修改TreeItem组件:

<template>
  <li>
    <div @click="toggle">
      <input 
        type="checkbox" 
        v-model="node.checked"
        @click.stop
      >
      {{ node.label }}
      <span v-if="hasChildren">{{ isOpen ? '-' : '+' }}</span>
    </div>
    <ul v-show="isOpen" v-if="hasChildren">
      <tree-item 
        v-for="child in node.children" 
        :key="child.id" 
        :node="child"
        @check-change="handleCheckChange"
      />
    </ul>
  </li>
</template>

<script>
export default {
  methods: {
    handleCheckChange(checked) {
      this.$emit('check-change', checked)
    }
  }
}
</script>

动态加载

实现懒加载子节点功能:

methods: {
  async toggle() {
    if (!this.hasChildren && this.node.loadOnDemand) {
      try {
        const children = await fetchChildren(this.node.id)
        this.$set(this.node, 'children', children)
        this.isOpen = true
      } catch (error) {
        console.error(error)
      }
    } else {
      this.isOpen = !this.isOpen
    }
  }
}

性能优化

对于大型树结构,使用虚拟滚动:

vue实现树形菜单组件

<template>
  <virtual-list :size="40" :remain="20">
    <tree-item 
      v-for="node in visibleNodes" 
      :key="node.id" 
      :node="node"
    />
  </virtual-list>
</template>

标签: 组件菜单
分享给朋友:

相关文章

vue哪个组件实现动画

vue哪个组件实现动画

在Vue中实现动画效果,可以通过以下组件和方法实现: Vue内置动画组件 Vue提供了<transition>和<transition-group>两个内置组件,用于处理进入…

vue实现折叠组件

vue实现折叠组件

实现折叠组件的基本思路 在Vue中实现折叠组件通常需要利用动态绑定和条件渲染。核心是通过控制一个布尔值状态来决定内容是否显示,并添加过渡动画提升用户体验。 基础实现方法 使用v-show或v-if控…

vue实现tooltips组件

vue实现tooltips组件

实现基础 Tooltip 组件 创建一个名为 Tooltip.vue 的单文件组件,包含模板、样式和逻辑: <template> <div class="tooltip-con…

vue实现水印组件

vue实现水印组件

Vue 水印组件的实现方法 使用Canvas绘制水印 在Vue组件中通过Canvas动态生成水印图案,将其作为背景添加到目标元素上。 <template> <div ref="…

vue表格组件实现

vue表格组件实现

Vue表格组件实现 基础表格实现 使用el-table组件实现基础表格功能。安装Element UI后,引入el-table和el-table-column组件。 <template>…

js实现下拉菜单

js实现下拉菜单

使用HTML和CSS创建基础结构 HTML部分需要包含一个触发下拉的按钮和隐藏的下拉菜单内容: <div class="dropdown"> <button class="dr…