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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue+ java 实现多级菜单递归效果

    效果如图: 大概思路:树形视图使用的是vue官方事例代码,java负责封装数据,按照vue官方事例的数据结构封装数据即可.有两个需要关注的点: 1.官方事例的数据结构是一个对象里面包含着集合,而不是一个集合对象 2.递归算法 上代码: 前端:html+js <html> <head> <meta charset="UTF-8"> <title></title> <script src="https://cdn.

  • vue实现多级菜单效果

    本次记录基于iview3框架实现多级菜单+vue router实现页面切换 方法一: 使用Tree 树形控件,官方文档 以官方demo为例,数据中添加URL属性,用于路由跳转,正式项目中该tree控件的数据由后端给出,需要注意的是后端给出的URL跳转地址最前一定要看清有没有"/" ,如果没有自己手动加或后端改,没有这个"/" 斜杠会导致路由跳转失败. 思路:根据官方文档里面写用on-select-change事件返回当前已选中的节点数组.当前项,就利用返回的当前项数

  • Vue 递归多级菜单的实例代码

    考虑以下菜单数据: [ { name: "About", path: "/about", children: [ { name: "About US", path: "/about/us" }, { name: "About Comp", path: "/about/company", children: [ { name: "About Comp A", path:

  • springboot + vue 实现递归生成多级菜单(实例代码)

    开发过程中,涉及到多级菜单的应用,找了一些资料案例实现如下(使用springboot+layui+oracle): 创建菜单表 : -- 创建菜单表 create table wxmini_menus( menu_id number unique, --菜单ID menu_name varchar2(20), menu_url varchar2(200), menu_icon varchar2(100), parent_id number, --父菜单ID status varchar2(10)

  • jdk1.8+vue elementui实现多级菜单功能

    前言:在学习谷粒商城的时候,在做分类维护树形菜单维护的功能中,项目中只讲了菜单三级树怎么实现,想拓展一下多级菜单,功能已实现,记录一下,有不对的地方欢迎指正. 一.后端部分 使用Jdk1.8的新特性Stream和lamada表达式,数据库的框架使用苞米豆的mybatis plus,话不多说,上代码 1. 新建ManyTree类,可封装成工具类 import com.atguigu.gulimall.product.entity.CategoryEntity; import com.google.

  • 详解VUE Element-UI多级菜单动态渲染的组件

    以下是组件代码: <template> <div class="navMenu"> <label v-for="navMenu in navMenus"> <el-menu-item v-if="navMenu.childs==null&&navMenu.entity&&navMenu.entity.state==='ENABLE'" :key="navMenu.

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

    本文实例为大家分享了vue递归组件实现elementUI多级菜单的具体代码,供大家参考,具体内容如下 先看效果: 一.子组件 <template>     <div class="myDiv">         <!-- 这里的listAll用于接收父组件传递进来的菜单列表 -->         <template v-for="(item,i) in listAll">             <!-- 有c

  • Vue递归组件+Vuex开发树形组件Tree--递归组件的简单实现

    写在前面 首先,本篇文章所开发的组件并非一个已经开源的上线组件,所以如果你急于需要一个插件来只做你的项目,那么并不能带给你及时的帮助.这个组件的开发预计写两篇文章,一遍写组件,一篇写组件逻辑.这篇文章也是我自己开发的从无到有的过程,所以它可以为你提供一些Tree组件开发的思路,代码写到一定程度,不能完全依赖插件了,有时间可以看看插件源码或者动手去开发,这样真的能加深对技术的掌握程度. 开发过程 1.数据仓库-Vuex 2.组件的循环创建-递归组件 需求决定了我的技术选型,项目需求是一个中国各级政

  • vue递归组件实战之简单树形控件实例代码

    1.递归组件-简单树形控件预览及问题 在编写树形组件时遇到的问题: 组件如何才能递归调用? 递归组件点击事件如何传递? 2.树形控件基本结构及样式 <template> <ul class="vue-tree"> <li class="tree-item"> <div class="tree-content"><!--节点内容--> <div class="expand-

  • vue 递归组件的简单使用示例

    前言 递归 相信很多同学已经不陌生了,算法中我们经常用递归来解决问题.比如经典的:从一个全为数字的数组中找出其中相加能等于目标数的组合.思路也不难,循环数组取值,不断递归相加,直到满足目标数条件.递归虽然能解决大部分,但弊处在于,很容易写出死循环的代码,导致爆栈.下面以我实际业务场景讲讲递归在vue组件中的应用. 在vue中使用 完成一个完整的递归,我个人认为最重要的有两点: 确定好进入递归的条件; 确定好跳出递归的条件; 其中最重要的就是确定 什么时候跳出递归.递归组件实际上非常简单,就是 A

  • vue递归组件实现树形结构

    本文实例为大家分享了vue递归组件实现树形结构,供大家参考,具体内容如下 一.递归组件 什么是递归组件?简单来说就是在组件中内使用组件本身.函数自己调用自己.很多情况下我们呢刷数据的时候,不知道到底这个数据结构是有多少层,那么这个时候我们就用到了递归来实现. 二.先用for来遍历: 父组件中: <template>   <div class="home">        <tree :title="list.name" :list=&q

  • vue3递归组件封装的全过程记录

    目录 前言 1.递归组件 2.右键菜单组件 总结 前言 今天在写项目时,遇到一个自定义右键菜单的需求.在菜单中还有子菜单,所以这个时候就要用到递归组件了.所以写下这篇文章来记录一下自己编写递归组件的过程. 1.递归组件    递归组件,顾名思义就是在组件本身内部调用自身.所以我们先构建一个组件,并在自身内部调用自身.常见的递归组件就是我们项目中经常会用到的树组件了.下面就是我自己实现的一个能够满足项目需求的递归组件的源码. <template> <ul class="list-

随机推荐