文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎么使用el-menu递归实现多级菜单组件

2023-07-06 01:48

关注

今天小编给大家分享一下怎么使用el-menu递归实现多级菜单组件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

1. 效果:

怎么使用el-menu递归实现多级菜单组件

怎么使用el-menu递归实现多级菜单组件

怎么使用el-menu递归实现多级菜单组件

2. 实现:

创建外层菜单AsideMenu.vue组件和子菜单项AsideSubMenu.vue组件,在AsideSubMenu中进行递归操作。

AsideMenu.vue文件内容如下:

<template>  <aside class="wrap">    <el-menu      :default-active="activeMenu"      router      :class="'menu-left'"      :default-openeds="openedsArr"      text-color="#fff"    >      <AsideSubMenu :menuData="menuData"></AsideSubMenu>    </el-menu>  </aside></template> <script>import AsideSubMenu from "./AsideSubMenu.vue";export default {  name: "AsideMenu",  components: {    AsideSubMenu,  },  props: {    menuData: {      type: Array,    },  },  computed: {    activeMenu() {      const route = this.$route;      const { meta, path } = route;      // 此处添加判断的原因见说明      if (meta.matchPath) {        return meta.matchPath;      } else {        return path;      }    },    // 设置默认展开菜单项    openedsArr() {      // const arr = this.menuData.map((item) => {      //   return item.title;      // });      // return arr;      return [];    },  },};</script>

判断高亮状态的activeMenu方法中的判断matchPath属性可以让多个路由不同的页面匹配同一个菜单高亮状态,因为菜单高亮状态是根据路由地址匹配的。如果两个不同的路由页面想公用同一个菜单高亮状态(如详情页面和列表页)就可以使用该方法实现。在router文件里设置meta对象,添加matchPath属性设置为想要共用的高亮状态的页面的路由地址。(有点绕????)

样式根据需求修改,示例中的样式如下(此处包含深浅两种主题的菜单样式):

<style scoped>aside {  height: 100%;  text-align: center;}.el-menu {  padding: 16px;  box-sizing: border-box;}.menu-left,.menu-left /deep/ .el-menu {  min-height: 100%;  background-color: #222653;}.menu-left .icon {  width: 20px;  margin-right: 9px;}.menu-left /deep/.el-submenu__title,.menu-left /deep/.el-menu-item {  box-sizing: border-box;  font-size: 14px;  font-family: PingFangSC-Regular, PingFang SC;  text-align: left;  color: #b3c0e7 !important;  background-color: #222653 !important;}.menu-left /deep/.el-submenu__title i {  color: #b3c0e7 !important;}.menu-left /deep/.el-submenu__title {  height: 54px;  line-height: 54px;  }.menu-left /deep/ .el-menu-item {  height: 52px;  line-height: 52px;}.menu-left /deep/.el-submenu .el-menu-item {  padding-left: 45px !important;}.menu-left /deep/.el-submenu.is-active,.menu-left /deep/.el-submenu.is-active .el-menu-item,.menu-left /deep/.el-submenu.is-active .el-submenu__title,.menu-left /deep/.el-menu-item.is-active {  background-color: #4880ff !important;}.menu-left /deep/.el-submenu.is-active {  border-radius: 10px;  overflow: hidden;}.menu-left /deep/ .el-menu-item.is-active {  border-radius: 10px;}.menu-left /deep/ .el-menu--inline .el-menu-item.is-active,.menu-left /deep/ .el-submenu.noIcon {  border-radius: 0;}.menu-left /deep/ .el-submenu.noIcon .el-submenu__title {  padding-left: 45px !important;}.menu-left /deep/ .el-submenu.noIcon .el-menu-item {  padding-left: 58px !important;}.menu-left /deep/.el-submenu.is-active > .el-submenu__title,.menu-left /deep/.el-submenu.is-active > .el-submenu__title i {  color: #ffffff !important;}.menu-left /deep/.el-menu-item:focus,.menu-left /deep/.el-menu-item:hover,.menu-left /deep/.el-menu-item.is-active {  color: #ffffff !important;  font-weight: 500;}.menu-left /deep/.el-menu-item.is-disabled {  padding-left: 45px !important;  color: #ffffff !important;} .menu-left-light {  height: 100%;  background-color: #f8f8f8;}.menu-left-light .icon {  width: 20px;  margin-right: 9px;}.menu-left-light /deep/.el-submenu__title,.menu-left-light /deep/.el-menu-item {  box-sizing: border-box;  font-size: 16px;  font-family: PingFangSC-Regular, PingFang SC;  text-align: left;  color: #333333;}.menu-left-light /deep/.el-submenu__title {  height: 52px;  line-height: 52px;  padding-left: 56px !important;}.menu-left-light /deep/.el-submenu__title:hover {  background-color: #ffffff !important;}.menu-left-light /deep/.el-submenu__icon-arrow {  right: 85px;}.menu-left-light /deep/.el-submenu__title i {  color: #333333;}.menu-left-light /deep/.el-menu-item {  height: 40px;  line-height: 40px;  padding-left: 82px !important;  border-left: 4px solid #ffffff;}.menu-left-light /deep/.el-menu-item:focus,.menu-left-light /deep/.el-menu-item:hover,.menu-left-light /deep/.el-menu-item.is-active {  background: rgba(31, 65, 219, 0.1) !important;  color: #1f41db !important;  border-color: #1f41db;}.menu-left-light /deep/.el-menu-item.is-disabled {  background: #ffffff !important;  color: #333333 !important;}</style>

AsideMenu.vue文件内容如下:

<template>  <div>    <template v-for="item in menuData">      <el-submenu        :key="item.path"        v-if="item.children && item.children.length > 0"        :index="item.path"        :class="item.icon ? '' : 'noIcon'"      >        <template slot="title">          <img            class="icon mr-r-10"            :src="              curRoute.indexOf(item.path) != -1 ? item.iconActive : item.icon            "          />          <span>{{ item.title }}</span>        </template>        <AsideSubMenu :menuData="item.children"></AsideSubMenu>      </el-submenu>      <el-menu-item        :key="item.id"        v-else        :index="item.path"        :disabled="item.disabled"      >        <template slot="title">          <img            class="icon mr-r-10"            :src="              curRoute.indexOf(item.path) != -1 ? item.iconActive : item.icon            "          />          <span>{{ item.title }}</span>        </template>      </el-menu-item>    </template>  </div></template>

判断如果有子菜单则进行遍历操作。同时此处根据是否有icon给el-submenu动态添加了一个类名:class="item.icon ? '' : 'noIcon'",这么做是由于高亮状态下的.el-submenu添加了圆角效果,在存在多层子菜单嵌套的情况下如果不清除圆角效果则会出现问题(见下图)。这个状态下不好用选择器选中需要操作的元素,因此根据是否有icon这个区别进行了区分。如果是整个菜单都没有icon的情况的话,那暂时还没想好应对策略。????

怎么使用el-menu递归实现多级菜单组件

<script>import AsideSubMenu from "./AsideSubMenu.vue";export default {  name: "AsideSubMenu",  components: {    AsideSubMenu,  },  props: {    menuData: {      type: Array,      default: () => {        return [];      },    },  },  computed: {    curRoute() {      return this.$route.path;    },  },};</script>

3. 使用组件:

代码如下:

<template>  <el-container class="container">    <el-aside width="320px">      <AsideMenu :menuData="menuData"></AsideMenu>    </el-aside>    <el-main>      <keep-alive :exclude="[]">        <router-view></router-view>      </keep-alive>    </el-main>  </el-container></template> <script>import AsideMenu from '@/components/AsideMenu.vue';export default {  name: 'MenuTest',  components: {    AsideMenu  },  data() {    return {      menuData: [        {          title: '菜单一',          path: '/menutest/menu1',          icon: require('@/assets/icons/apply.svg'),          iconActive: require('@/assets/icons/apply_active.svg'),          children: [            {              title: '子菜单一',              path: '/menutest/menu1/menu1-1',              // disabled: true,            },            {              title: '子菜单二',              path: '/menutest/menu1/menu1-2'            }          ]        },        {          title: '菜单二',          path: '/menutest/menu2',          icon: require('@/assets/icons/apply.svg'),          iconActive: require('@/assets/icons/apply_active.svg'),          children: [            {              title: '子菜单一',              path: '/menutest/menu2/menu2-1'            },            {              title: '子菜单二',              path: '/menutest/menu2/menu2-2',              children: [                {                  title: '孙子菜单一',                  path: '/menutest/menu2/menu2-2/menu2-1-1'                },                {                  title: '孙子菜单二',                  path: '/menutest/menu2/menu2-2/menu2-2-2'                }              ]            },            {              title: '子菜单三',              path: '/menutest/menu2/menu2-3'            }          ]        },        {          title: '菜单三',          path: '/menutest/menu3',          icon: require('@/assets/icons/apply.svg'),          iconActive: require('@/assets/icons/apply_active.svg'),        }      ]    };  }};</script> <style scoped>.container {  min-height: 800px;}.el-main {  padding: 32px 40px;  box-sizing: border-box;  background: #f5f5fa;  overflow-y: auto;}</style>

示例中的路由配置如下:

  {    path: "/menutest",    name: "Menu",    component: () => import("../views/MenuTest.vue"),    redirect: "/menutest/menu1",    children: [{        path: '/menutest/menu1',        component: () => import("../views/menuPages/menu1.vue"),        children: [{            path: '/menutest/menu1/menu1-1',            component: () => import("../views/menuPages/menu1-1.vue"),          },          {            path: '/menutest/menu1/menu1-2',            component: () => import("../views/menuPages/menu1-2.vue"),          }        ]      },      {        path: '/menutest/menu2',        component: () => import("../views/menuPages/menu2.vue"),        children: [{            path: '/menutest/menu2/menu2-1',            component: () => import("../views/menuPages/menu2-1.vue"),          },          {            path: '/menutest/menu2/menu2-2',            component: () => import("../views/menuPages/menu2-2.vue"),            children: [{                path: '/menutest/menu2/menu2-2/menu2-1-1',                component: () => import("../views/menuPages/menu2-1-1.vue"),              },              {                path: '/menutest/menu2/menu2-2/menu2-2-2',                component: () => import("../views/menuPages/menu2-1-2.vue"),              }            ]          },          {            path: '/menutest/menu2/menu2-3',            component: () => import("../views/menuPages/menu2-3.vue"),          }        ]      },      {        path: '/menutest/menu3',        component: () => import("../views/menuPages/menu3.vue"),      }    ]  }

以上就是“怎么使用el-menu递归实现多级菜单组件”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯