vue递归组件如何实现elementUI多级菜单

每到春天,红得如火的木棉花,粉得如霞的芍药花,白得如玉的月季花竞相开放。它们有的花蕾满枝,有的含苞初绽,有的昂首怒放。一阵沁人心肺的花香引来了许许多多的小蜜蜂,嗡嗡嗡地边歌边舞。

本文实例为大家分享了vue递归组件实现elementUI多级菜单的具体代码,供大家参考,具体内容如下

先看效果:

一、子组件

<template>
  <div class="myDiv">
    <!-- 这里的listAll用于接收父组件传递进来的菜单列表 -->
    <template v-for="(item,i) in listAll">
      <!-- 有child就显示child的下拉型菜单,有小箭头 -->
      <el-submenu :index="item.index" :key="i" v-if="item.child.length!=0">
        <template slot="title">
          <img :src="item.img" alt="">
          <span>{{item.title}}</span>
        </template>
        <!-- 再次调用自身组件,传入子集,进行循环递归调用 -->
        <Menu :listAll="item.child"></Menu>
      </el-submenu>
      <!-- 没有child,就显示单个目录,没有小箭头 -->
      <el-menu-item :index="item.index" v-else :key="i" @click="handleSelect(item.path,item.title,item.index)">
        <span slot="title"><img :src="item.img" alt="">{{item.title}}</span>
      </el-menu-item>
    </template>
  </div>
</template>

<script>
export default {
  name: "Menu',
  components: {},
  props: ['listAll'],
  data() {
    return {
      realList: this.listAll,
    }
  },
  methods: {
    //设置路由跳转
    handleSelect(path, name, selfIndex) {
      this.$router.push(
        {
          path: "/" + path,
          query: {
            r_n: name,
            index: selfIndex
          }
        }
      )
    },
   
  },
}
</script>

二、菜单数据准备

菜单中包含索引,图片,名称,跳转路径,这里我给出一部分数据,路由直接用数字了,你们最好定义为组件的英文名称,这样方便维护。

export function menuJson() {
 var data = [{
  title: "元数据管理",
  img: "../../../static/img/manager.png",
  index: '1',
  child: [
   {
    "title": "元数据信息描述管理", "path": "main/02/005", "img": "../../../static/img/manager.png", "index": "1-2", "child": []
   },
   {
    "title": "元数据分组定义管理", "path": "main/02/007", "img": "../../../static/img/manager.png", "index": "1-3", "child": []
   },
   {
    "title": "元数据信息管理", "path": "main/02", "img": "../../../static/img/manager.png", "index": "1-1", "child": [
     { "title": "采集元数据", "path": "main/02/001", "index": "1-1-1", "img": "../../../static/img/blood.png", "child": [] },
     { "title": "元模型", "path": "main/02/004", "index": "1-2-1", "img": "../../../static/img/blood.png", "child": [] },
    ]
   },

   {
    "title": "元数据统计分析管理", "path": "main/01", "index": "1-4", "img": "../../../static/img/manager.png", "child": [
     { "title": "元数据变更管理", "path": "main/01/001", "index": "1-4-1", "img": "../../../static/img/blood.png", "child": [] },
     { "title": "数据地图", "path": "main/01/002", "index": "1-4-2", "img": "../../../static/img/blood.png", "child": [] },
     {
      "title": "元数据分析", "path": "main/01/003", "index": "1-4-3", "img": "../../../static/img/yuanfenxi.png", "child": [

       { "title": "血缘分析", "path": "main/01/003/0001", "index": "1-4-3-1", "img": "../../../static/img/blood.png", "child": [] },
       { "title": "属性差异分析", "path": "main/01/003/0003", "index": "1-4-3-2", "img": "../../../static/img/chayi.png", "child": [] },
       { "title": "影响分析", "path": "main/01/003/0004", "index": "1-4-3-3", "img": "../../../static/img/impact.png", "child": [] },
      ]
     },

    ]
   },
  ]
 },
 {
  title: "规则管理",
  img: "../../../static/img/manager.png",
  index: '2',
  child: [
   { "title": "数据接口定义管理", "index": "2-1", "path": "main/03/001", "img": "../../../static/img/source.png", "child": [] },
   { "title": "数据转换规则管理", "index": "2-2", "path": "main/03/004", "img": "../../../static/img/modify.png", "child": [] },
  ]
 }
 ]
 return data
}

三、父组件调用

<template>
  <div class="content menu">
    <div class="menu_com" :style="{height:scrollHeight+'px'}">
      <el-col :span="24">
        <el-menu :default-active="activeIndex" class="el-menu-vertical-demo" :default-openeds="defalutIndex" background-color="#003289" text-color="#fff" active-text-color="#ffd04b">
          //调用子组件
          <Menu :listAll="listAll"></Menu>
        </el-menu>
      </el-col>
    </div>
  </div>
</template>

<script>
import Menu from './menu'
import { menuJson } from '../../assets/common/http' //调用js文件中的菜单数据
export default {
  name: "Menus",
  mixins: [mixin],
  components: { Menu },
  data() {
    return {
      scrollHeight: 400,
      listAll: [],
      activeIndex: "-1",
      defalutIndex: []
    }
  },
  created() {
    //设置点击菜单的索引,可以使得刷新后菜单仍保持原来查看的页面
    this.activeIndex = String(this.$route.query.index);
    this.listAll = menuJson() //通过调用函数menuJson,获取菜单
  },
  watch: {
    $route(to, from) {
      this.activeIndex = this.$route.query.index;
    }
  },
}
</script>

<style scoped lang="less">
@color: #003289;
  .menu {
    background: @color;

    > div {
      width: 100%;
      padding-top: 20px;
      // height: 100%;
      color: #ffffff;
      overflow-y: scroll;
      overflow-x: hidden;
      &::-webkit-scrollbar {
        display: none;
      }
      h1 {
        font-size: 20px;
        text-align: center;
        padding: 15px 0 25px 0;
      }
    }
  }
  .el-menu-demo {
    position: absolute;
    height: 58px !important;
    left: 25%;
    top: 0%;
  }

</style>

补充(面包屑的展示):

有菜单,肯定需要面包屑的展示,例如

这里我用的方法是,根据当前页面名称,从树形菜单数据中查找它的所有父级来实现面包屑导航栏的展示。

html:

<el-breadcrumb separator-class="el-icon-arrow-right">
  <el-breadcrumb-item v-for="(item,index) in listMenu" :key="index">{{item}}</el-breadcrumb-item>
</el-breadcrumb>

methods:

methods: {
//获取树形数据的某个元素的所有父节点
    getTreePath(tree, func, path) {
      if (!tree) return []
      for (const data of tree) {
        // 这里按照你的需求来存放最后返回的内容吧
        //这里的title是我的菜单数据里面的名称字段,你可以改成你的
        path.push(data.title)
        if (func(data)) return path
        if (data.child) {
          //获取到子数据,递归调用
          const findChildren = this.getTreePath(data.child, func, path)
          if (findChildren.length) return findChildren
        }
        path.pop()
      }
      return []
    },
    // 获取面包屑
    getNavList() {
      var name = this.$route.query.r_n //先获取当前路由名称
      var tree = menuJson() //获取菜单数据,menuJson这个函数上面用了,返回的事菜单数据
      this.path = [] //path用于存放所有父级,调用前需要清空
      //data => data.title === name查找数据中的title是否和当前路由名称相等
      this.getTreePath(tree, data => data.title === name, this.path)
      this.listMenu = this.path //找到之后赋值给面包屑路由数组
      console.log(this.listMenu)
    }
  }

以上就是vue递归组件如何实现elementUI多级菜单。无论你身处何境都是自己的选择。更多关于vue递归组件如何实现elementUI多级菜单请关注haodaima.com其它相关文章!

您可能有感兴趣的文章
vue如何实现列表固定列滚动

vue如何实现移动端拖拽悬浮按钮

vue如何实现伸缩菜单功能

Vue如何实现可复用轮播组件的方法

vue项目中canvas如何实现截图功能