当前位置:首页 > 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 倒计时组件实现 核心思路 通过 setInterval 或 setTimeout 实现时间递减,结合 Vue 的响应式数据更新 UI。需注意组件销毁时清除定时器。 基础实现方案 模板部分…

elementui组件

elementui组件

ElementUI 组件概述 ElementUI 是一套基于 Vue.js 的桌面端组件库,提供丰富的 UI 组件,适用于快速开发中后台系统。以下是其核心组件分类及典型用法。 基础组件 Button…

css div 制作导航菜单

css div 制作导航菜单

使用 CSS 和 Div 制作导航菜单 导航菜单是网站的重要组成部分,以下是通过 CSS 和 div 元素制作导航菜单的方法。 基本 HTML 结构 创建一个简单的 div 结构作为导航菜单的基础:…

react如何删除组件

react如何删除组件

删除 React 组件的几种方法 条件渲染法 通过状态控制组件是否渲染。当状态为 false 时,组件会被移除: const [showComponent, setShowComponent…

js实现导航菜单

js实现导航菜单

使用HTML和CSS创建基础结构 导航菜单的基础结构通常由HTML的无序列表(<ul>)和列表项(<li>)组成,每个列表项包含一个链接(<a>)。CSS用于样式化…

vue实现组件切换

vue实现组件切换

Vue 组件切换的实现方法 在 Vue 中实现组件切换有多种方式,以下是几种常见的方法: 动态组件 使用 Vue 内置的 <component> 元素和 is 属性可以动态切换组件:…