资讯专栏INFORMATION COLUMN

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

3403771864 / 1010人阅读

  效果展示:

  一、子组件

</>复制代码

  1.   <template>
  2.   <div class="myDiv">
  3.   <!-- 这里的listAll用于接收父组件传递进来的菜单列表 -->
  4.   <template v-for="(item,i) in listAll">
  5.   <!-- 有child就显示child的下拉型菜单,有小箭头 -->
  6.   <el-submenu :index="item.index" :key="i" v-if="item.child.length!=0">
  7.   <template slot="title">
  8.   <img :src="item.img" alt="">
  9.   <span>{{item.title}}</span>
  10.   </template>
  11.   <!-- 再次调用自身组件,传入子集,进行循环递归调用 -->
  12.   <Menu :listAll="item.child"></Menu>
  13.   </el-submenu>
  14.   <!-- 没有child,就显示单个目录,没有小箭头 -->
  15.   <el-menu-item :index="item.index" v-else :key="i" @click="handleSelect(item.path,item.title,item.index)">
  16.   <span slot="title"><img :src="item.img" alt="">{{item.title}}</span>
  17.   </el-menu-item>
  18.   </template>
  19.   </div>
  20.   </template>
  21.   <script>
  22.   export default {
  23.   name: 'Menu',
  24.   components: {},
  25.   props: ['listAll'],
  26.   data() {
  27.   return {
  28.   realList: this.listAll,
  29.   }
  30.   },
  31.   methods: {
  32.   //设置路由跳转
  33.   handleSelect(path, name, selfIndex) {
  34.   this.$router.push(
  35.   {
  36.   path: "/" + path,
  37.   query: {
  38.   r_n: name,
  39.   index: selfIndex
  40.   }
  41.   }
  42.   )
  43.   },
  44.   },
  45.   }
  46.   </script>

  二、菜单数据准备

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

</>复制代码

  1.   export function menuJson({
  2.   var data = [{
  3.   title: "元数据管理",
  4.   img: "../../../static/img/manager.png",
  5.   index'1',
  6.   child: [
  7.   {
  8.   "title""元数据信息描述管理""path""main/02/005""img""../../../static/img/manager.png""index""1-2""child": []
  9.   },
  10.   {
  11.   "title""元数据分组定义管理""path""main/02/007""img""../../../static/img/manager.png""index""1-3""child": []
  12.   },
  13.   {
  14.   "title""元数据信息管理""path""main/02""img""../../../static/img/manager.png""index""1-1""child": [
  15.   { "title""采集元数据""path""main/02/001""index""1-1-1""img""../../../static/img/blood.png""child": [] },
  16.   { "title""元模型""path""main/02/004""index""1-2-1""img""../../../static/img/blood.png""child": [] },
  17.   ]
  18.   },
  19.   {
  20.   "title""元数据统计分析管理""path""main/01""index""1-4""img""../../../static/img/manager.png""child": [
  21.   { "title""元数据变更管理""path""main/01/001""index""1-4-1""img""../../../static/img/blood.png""child": [] },
  22.   { "title""数据地图""path""main/01/002""index""1-4-2""img""../../../static/img/blood.png""child": [] },
  23.   {
  24.   "title""元数据分析""path""main/01/003""index""1-4-3""img""../../../static/img/yuanfenxi.png""child": [
  25.   { "title""血缘分析""path""main/01/003/0001""index""1-4-3-1""img""../../../static/img/blood.png""child": [] },
  26.   { "title""属性差异分析""path""main/01/003/0003""index""1-4-3-2""img""../../../static/img/chayi.png""child": [] },
  27.   { "title""影响分析""path""main/01/003/0004""index""1-4-3-3""img""../../../static/img/impact.png""child": [] },
  28.   ]
  29.   },
  30.   ]
  31.   },
  32.   ]
  33.   },
  34.   {
  35.   title: "规则管理",
  36.   img: "../../../static/img/manager.png",
  37.   index'2',
  38.   child: [
  39.   { "title""数据接口定义管理""index""2-1""path""main/03/001""img""../../../static/img/source.png""child": [] },
  40.   { "title""数据转换规则管理""index""2-2""path""main/03/004""img""../../../static/img/modify.png""child": [] },
  41.   ]
  42.   }
  43.   ]
  44.   return data
  45.   }

  三、父组件调用

</>复制代码

  1.   <template>
  2.   <div class="content menu">
  3.   <div :style="{height:scrollHeight+'px'}">
  4.   <el-col :span="24">
  5.   <el-menu :default-active="activeIndex" :default-openeds="defalutIndex" background-color="#003289" text-color="#fff" active-text-color="#ffd04b">
  6.   //调用子组件
  7.   <Menu :listAll="listAll"></Menu>
  8.   </el-menu>
  9.   </el-col>
  10.   </div>
  11.   </div>
  12.   </template>
  13.   <script>
  14.   import Menu from './menu'
  15.   import { menuJson } from '../../assets/common/http' //调用js文件中的菜单数据
  16.   export default {
  17.   name: "Menus",
  18.   mixins[mixin],
  19.   components: { Menu },
  20.   data() {
  21.   return {
  22.   scrollHeight: 400,
  23.   listAll[],
  24.   activeIndex: "-1",
  25.   defalutIndex: []
  26.   }
  27.   },
  28.   created() {
  29.   //设置点击菜单的索引,可以使得刷新后菜单仍保持原来查看的页面
  30.   this.activeIndex = String(this.$route.query.index);
  31.   this.listAll = menuJson() //通过调用函数menuJson,获取菜单
  32.   },
  33.   watch: {
  34.   $route(to, from) {
  35.   this.activeIndex = this.$route.query.index;
  36.   }
  37.   },
  38.   }
  39.   </script>
  40.   <style scoped>
  41.   @color: #003289;
  42.   .menu {
  43.   background: @color;
  44.   > div {
  45.   width: 100%;
  46.   padding-top: 20px;
  47.   // height: 100%;
  48.   color: #ffffff;
  49.   overflow-y: scroll;
  50.   overflow-x: hidden;
  51.   &::-webkit-scrollbar {
  52.   display: none;
  53.   }
  54.   h1 {
  55.   font-size: 20px;
  56.   text-align: center;
  57.   padding: 15px 0 25px 0;
  58.   }
  59.   }
  60.   }
  61.   .el-menu-demo {
  62.   position: absolute;
  63.   height: 58px !important;
  64.   left: 25%;
  65.   top: 0%;
  66.   }
  67.   </style>

  补充(面包屑的展示):

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

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

  html:

</>复制代码

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

</>复制代码

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


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/127672.html

相关文章

  • Vue2.0 + ElementUI 手写权限管理系统后台模板(一)——简述

    摘要:简介最近写了一个基于权限管理系统的后台模板,包含了正常项目开发所需的框架功能,开发者使用的时候只需要专注于项目的业务逻辑就好。同时接下来会让你拥有一个自己完全掌控的框架。 简介 最近写了一个基于vue2.0+element-ui权限管理系统的后台模板,包含了正常项目开发所需的框架功能,开发者使用的时候只需要专注于项目的业务逻辑就好。同时接下来会让你拥有一个自己完全掌控的框架。 源码地址...

    _ivan 评论0 收藏0
  • vue多级菜单(路由)导致缓存(keep-alive)失效

    摘要:造成这个问题的原因是多级路由组件嵌套。当点击菜单的时候,由于设置的不缓存,所以导致组件被销毁这就是为什么会失效的根本原因。既然这样的话,显示的菜单保留多级的,实际的弄成一级,将显示菜单和业务分离开。 一般的后台管理系统功能都比较繁多,存在有多级菜单的需求,但是在这种项目里往往keep-alive的表现却非常不稳定,有时候某个页面可以缓存,但是点几下就发现缓存丢了;有时候不知道怎么回事又...

    big_cat 评论0 收藏0
  • Vue + Vue-router + Element-ui 搭建一个非常简单的dashboard d

    摘要:但是有边框,不好看啊再次美化使用使用图标库安装这里主要贴一下的改动,其他的代码就不贴了看下效果图标什么的都有了。另外文件需要加上看看效果点击菜单,路径跳转,并且每次都是单独去加载路由的文件。 做完这个demo后,我体会到,Vue组件化,webpack, Vue-router等,并不是很难学习,你需要的只是拿起斧头的勇气在做demo的过程中,我遇到一个问题,就是vue-router懒加载...

    Near_Li 评论0 收藏0
  • 封装框架的实践

    摘要:最近在尝试着封装一个框架,碍于种种原因,先从简单的入手吧。基于和封装的框架,集成数据存储字体图标库拓展语言网络请求等模块,为了让业务开发更专注于数据驱动。 最近在尝试着封装一个框架,碍于种种原因,先从简单的入手吧。基于vue和elementUI封装的框架,集成 数据存储localforage、字体图标库font-awesome、css拓展语言scss、网络请求axios等模块,为了让业...

    Dogee 评论0 收藏0
  • 管理系统之权限的设计和实现

    摘要:基本设计和分析前端服务端主要功能打开思否页面,根据页面的功能点,设计出相关的数据表,和管理系统需要的相关页面。 本文主要想对前端权限管理功能实现做一个分享,所以并不会对后台管理的框架结构做太详细介绍,如果有朋友对其他有兴趣可以留言。 基本设计和分析 前端 vue + elementui 服务端: node + mysql + nginx 主要功能 打开思否页面,根据页面的功能点,设...

    googollee 评论0 收藏0

发表评论

0条评论

3403771864

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<