当前位置:首页 > VUE

vue实现树形菜单组件

2026-01-20 23:30:10VUE

vue实现树形菜单组件

数据准备

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

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

递归组件实现

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

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组件:

vue实现树形菜单组件

<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
    }
  }
}

性能优化

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

<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 组件实现方法 单文件组件 (SFC) 使用 .vue 文件格式,包含模板、脚本和样式三部分: <template> <div class="example">{{…

vue elementui实现菜单

vue elementui实现菜单

Vue ElementUI 实现菜单 安装 ElementUI 确保项目已安装 Vue 和 ElementUI。若未安装,可以通过以下命令安装: npm install element-ui 在 m…

vue实现tooltips组件

vue实现tooltips组件

Vue实现Tooltips组件的方法 基础实现:使用Vue指令 创建一个自定义指令v-tooltip,通过鼠标事件触发提示框的显示与隐藏。 Vue.directive('tooltip', {…

vue实现导航菜单

vue实现导航菜单

Vue 实现导航菜单的方法 基础路由导航实现 在 Vue 项目中,使用 vue-router 可以轻松实现导航菜单功能。首先安装并配置路由: npm install vue-router 在 rou…

css div 制作导航菜单

css div 制作导航菜单

基本导航菜单结构 使用HTML创建一个简单的导航菜单结构,通常使用<ul>和li>列表实现。每个菜单项用<a>标签包裹以实现链接功能。 <div class="n…

纯css制作tab菜单

纯css制作tab菜单

纯CSS制作Tab菜单的方法 使用radio input控制切换 通过<input type="radio">和<label>元素配合实现无JavaScript的Tab切换效果…