当前位置:首页 > VUE

vue树形菜单实现

2026-01-18 09:56:17VUE

Vue 树形菜单实现方法

使用递归组件实现树形结构

递归组件是 Vue 中实现树形菜单的常见方式。通过组件自身调用自身,可以轻松处理嵌套的树形数据。

<template>
  <ul>
    <li v-for="item in treeData" :key="item.id">
      {{ item.label }}
      <tree-menu v-if="item.children" :treeData="item.children"></tree-menu>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'TreeMenu',
  props: {
    treeData: {
      type: Array,
      required: true
    }
  }
}
</script>

添加展开/折叠功能

为树形菜单添加交互功能,允许用户展开或折叠子菜单。

<template>
  <ul>
    <li v-for="item in treeData" :key="item.id">
      <span @click="toggle(item)">
        {{ item.expanded ? '▼' : '►' }} {{ item.label }}
      </span>
      <tree-menu 
        v-if="item.children && item.expanded" 
        :treeData="item.children"
      ></tree-menu>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'TreeMenu',
  props: {
    treeData: Array
  },
  methods: {
    toggle(item) {
      this.$set(item, 'expanded', !item.expanded)
    }
  }
}
</script>

使用第三方库

对于更复杂的需求,可以考虑使用专门处理树形结构的 Vue 组件库。

安装 element-ui 的树形组件:

npm install element-ui

使用示例:

<template>
  <el-tree
    :data="treeData"
    :props="defaultProps"
    @node-click="handleNodeClick"
  ></el-tree>
</template>

<script>
import { ElTree } from 'element-ui'

export default {
  components: {
    ElTree
  },
  data() {
    return {
      treeData: [{
        label: '一级 1',
        children: [{
          label: '二级 1-1'
        }]
      }],
      defaultProps: {
        children: 'children',
        label: 'label'
      }
    }
  },
  methods: {
    handleNodeClick(data) {
      console.log(data)
    }
  }
}
</script>

动态加载数据

对于大型树形结构,可以实现懒加载功能,只在展开时加载子节点数据。

<template>
  <ul>
    <li v-for="item in treeData" :key="item.id">
      <span @click="loadChildren(item)">
        {{ item.hasChildren ? (item.expanded ? '▼' : '►') : '' }} {{ item.label }}
      </span>
      <tree-menu 
        v-if="item.children && item.expanded" 
        :treeData="item.children"
      ></tree-menu>
    </li>
  </ul>
</template>

<script>
export default {
  methods: {
    async loadChildren(item) {
      if (!item.expanded && item.hasChildren && !item.children) {
        const children = await fetchChildren(item.id)
        this.$set(item, 'children', children)
      }
      this.$set(item, 'expanded', !item.expanded)
    }
  }
}
</script>

样式优化

为树形菜单添加基本样式,提升用户体验。

ul {
  list-style-type: none;
  padding-left: 20px;
}

li {
  margin: 5px 0;
  cursor: pointer;
}

span:hover {
  background-color: #f5f5f5;
}

完整示例

结合上述功能的完整树形菜单组件示例:

<template>
  <ul class="tree-menu">
    <li v-for="item in treeData" :key="item.id">
      <div class="node" @click="toggleNode(item)">
        <span class="toggle-icon">
          {{ item.children && item.children.length ? (item.expanded ? '▼' : '►') : '' }}
        </span>
        <span class="node-label">{{ item.label }}</span>
      </div>
      <tree-menu 
        v-if="item.children && item.expanded" 
        :treeData="item.children"
        class="sub-tree"
      ></tree-menu>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'TreeMenu',
  props: {
    treeData: {
      type: Array,
      required: true
    }
  },
  methods: {
    toggleNode(item) {
      this.$set(item, 'expanded', !item.expanded)
    }
  }
}
</script>

<style scoped>
.tree-menu {
  list-style: none;
  padding-left: 20px;
}

.node {
  display: flex;
  align-items: center;
  padding: 5px 0;
  cursor: pointer;
}

.toggle-icon {
  display: inline-block;
  width: 20px;
}

.node-label {
  margin-left: 5px;
}

.node:hover {
  background-color: #f0f0f0;
}

.sub-tree {
  margin-left: 15px;
}
</style>

vue树形菜单实现

标签: 菜单vue
分享给朋友:

相关文章

vue.js实现轮播

vue.js实现轮播

vue.js实现轮播的方法 使用第三方库(如Swiper) 安装Swiper库: npm install swiper 在Vue组件中引入Swiper: <template>…

vue实现自动翻译

vue实现自动翻译

Vue 实现自动翻译的方法 在 Vue 项目中实现自动翻译功能可以通过多种方式完成,以下是几种常见的方法: 使用第三方翻译 API 注册并获取翻译 API 的密钥(如 Google Transla…

vue实现选择季度

vue实现选择季度

Vue 实现选择季度的几种方法 使用下拉选择框(Select) 在 Vue 中可以通过 v-model 绑定一个下拉选择框来实现季度选择。数据可以预先定义为一个包含季度选项的数组。 <tem…

vue怎么实现动画

vue怎么实现动画

Vue 动画实现方法 Vue 提供了多种方式实现动画效果,包括内置过渡系统、第三方库集成以及 CSS 动画。以下是常见实现方法: 使用 Vue 过渡系统 通过 <transition>…

vue实现展开与收起

vue实现展开与收起

Vue 实现展开与收起功能 在 Vue 中实现展开与收起功能可以通过多种方式完成,以下是一些常见的方法: 使用 v-show 或 v-if 控制显示 通过 Vue 的指令 v-show 或 v-i…

vue实现视频会议

vue实现视频会议

使用 Vue 实现视频会议 技术选型 Vue.js 作为前端框架,结合 WebRTC 技术实现实时音视频通信。常用的库包括: peerjs:简化 WebRTC 的点对点连接。 socket.io:用…