Vue iview-admin框架二级菜单改为三级菜单的方法


Posted in Javascript onJuly 03, 2018

最近在用 iview-admin的Vue后台模板,从git上下载后发现左侧导航栏最多支持到二级菜单,也发现很多童鞋在问如何实现三级菜单。在实际的应用场景中还是会出现三级菜单的需求的,木有其他好办法,只能自己手动改代码了。

1. 第一步:首先改写VUE中的模板,修改sidebarMenu.vue文件,文件具体目录建下图:

Vue iview-admin框架二级菜单改为三级菜单的方法

将Menu导航菜单组件的的二级嵌套结构改为三级嵌套,无非就是判断二级路由页面下是否有children属性及是否含有子元素,有的话直接v-for循环生成子元素标签,新结构如下:

<template>
 <Menu ref="sideMenu" :active-name="$route.name" :open-names="openNames" :theme="menuTheme" width="auto" @on-select="changeMenu">
  <template v-for="item in menuList">
   <MenuItem v-if="item.children.length<=1" :name="item.children[0].name" :key="'menuitem' + item.name">
    <Icon :type="item.children[0].icon || item.icon" :size="iconSize" :key="'menuicon' + item.name"></Icon>
    <span class="layout-text" :key="'title' + item.name">{{ itemTitle(item.children[0]) }}</span>
   </MenuItem>

   <Submenu v-if="item.children.length > 1" :name="item.name" :key="item.name">
    <template slot="title">
     <Icon :type="item.icon" :size="iconSize"></Icon>
     <span class="layout-text">{{ itemTitle(item) }}</span>
    </template>
    <template v-for="child in item.children">
     <!-- 添加条件判断是否还有三级菜单 v-if="child.children.length<=1" -->
     <MenuItem v-if="isThirdLeveMenu(child)==false" :name="child.name" :key="'menuitem' + child.name">
      <Icon :type="child.icon" :size="iconSize" :key="'icon' + child.name"></Icon>
      <span class="layout-text" :key="'title' + child.name">{{ itemTitle(child) }}</span>
     </MenuItem>
     <!-- 以下为新增 添加条件判断如果有三级菜单 则增加三级菜单 -->
     <Submenu v-if="isThirdLeveMenu(child)==true" :name="child.name" :key="'menuitem' + child.name">
       <template slot="title">
        <Icon :type="child.icon" :size="iconSize" :key="'icon' + child.name"></Icon>
        <span class="layout-text" :key="'title' + child.name">{{ itemTitle(child) }}</span>
       </template>
       <template v-for="son in child.children">
        <MenuItem :name="son.name" :key="'menuitem' + son.name">
         <Icon :type="son.icon" :size="iconSize" :key="'icon' + son.name"></Icon>
         <span class="layout-text" :key="'title' + son.name">{{ itemTitle(son) }}</span>
        </MenuItem>
       </template>
     </Submenu>
     <!-- 以上为新增 -->
    </template>
   </Submenu>
  </template>
 </Menu>
</template>

组件中methods下添加一个方法isThirdLeveMenu,判断是否含有children属性:

methods: {
 changeMenu(active) {
  this.$emit("on-change", active);
 },
 itemTitle(item) {
  if (typeof item.title === "object") {
  return this.$t(item.title.i18n);
  } else {
  return item.title;
  }
 },
 isThirdLeveMenu(child){
  if(child.children){
   if(child.children.length>0)return true;
   else return false;
  }
  else {
   return false;
  }
 }
 },

第二步:修改创建当前path路径的逻辑方法:setCurrentPath ,在libs文件夹下util.js文件中:

util.setCurrentPath = function (vm, name) {
 let title = '';
 let isOtherRouter = false;
 vm.$store.state.app.routers.forEach(item => {
  if (item.children.length === 1) {
   if (item.children[0].name === name) {
    title = util.handleTitle(vm, item);
    if (item.name === 'otherRouter') {
     isOtherRouter = true;
    }
   }
  } else {
   item.children.forEach(child => {
    if (child.name === name) {
     title = util.handleTitle(vm, child);
     if (item.name === 'otherRouter') {
      isOtherRouter = true;
     }
    }
   });
  }
 });
 let currentPathArr = [];
 //去首页
 if (name === 'home_index') {
  currentPathArr = [
   {
    title: util.handleTitle(vm, util.getRouterObjByName(vm.$store.state.app.routers, 'home_index')),
    path: '',
    name: 'home_index'
   }
  ];
 } 
 //去导航菜单一级页面或者OtherRouter路由中的页面
 else if ((name.indexOf('_index') >= 0 || isOtherRouter) && name !== 'home_index') {
  currentPathArr = [
   {
    title: util.handleTitle(vm, util.getRouterObjByName(vm.$store.state.app.routers, 'home_index')),
    path: '/home',
    name: 'home_index'
   },
   {
    title: title,
    path: '',
    name: name
   }
  ];
 } 
 //去导航菜单二级页面或三级页面
 else {
  let currentPathObj = vm.$store.state.app.routers.filter(item => {

   var hasMenu;
   if (item.children.length <= 1) {
    hasMenu = item.children[0].name === name;
    return hasMenu;
   } else {
    let i = 0;
    let childArr = item.children;
    let len = childArr.length;
    while (i < len) {
     //如果是三级页面按钮,则在二级按钮数组中找不到这个按钮名称
     //需要二级页面下可能出现三级子菜单的情况逻辑加入
     if (childArr[i].name === name) {
      hasMenu = true;
      return hasMenu;
     }
     i++;
    }
    //如果一级,二级菜单下都没有此按钮名称,则遍历三级菜单
    if(!hasMenu){
     for(let m=0;m<childArr.length;m++){
      if(!childArr[m].children) continue;
      let sonArr = childArr[m].children;
      for(let n=0;n<sonArr.length;n++){
       if(sonArr[n].name === name){
        hasMenu = true;
        return hasMenu;
       }
      }
     }
    }
    return false;
   }
  })[0];
  
  if (currentPathObj.children.length <= 1 && currentPathObj.name === 'home') {
   currentPathArr = [
    {
     title: '首页',
     path: '',
     name: 'home_index'
    }
   ];
  } else if (currentPathObj.children.length <= 1 && currentPathObj.name !== 'home') {
   currentPathArr = [
    {
     title: '首页',
     path: '/home',
     name: 'home_index'
    },
    {
     title: currentPathObj.title,
     path: '',
     name: name
    }
   ];
  } else {
    //如果是三级页面按钮,则在二级按钮数组中找不到这个按钮名称
    //需要二级页面下可能出现三级子菜单的情况逻辑加入
   let childObj = currentPathObj.children.filter((child) => {
    return child.name === name;
   })[0];

   // let thirdLevelObj =
   console.log(childObj)
   //二级页面
   if (childObj) {
    currentPathArr = [
     {
      title: '首页',
      path: '/home',
      name: 'home_index'
     },
     {
      title: currentPathObj.title,
      path: '',
      name: currentPathObj.name
     },
     {
      title: childObj.title,
      path: currentPathObj.path + '/' + childObj.path,
      name: name
     }
    ];
   }
   //childobj为undefined,再从三级页面中遍历
   else {
    let thirdObj;
    let childObj = currentPathObj.children.filter((child) => {
     let hasChildren;
     hasChildren = child.name === name;
     if (hasChildren) return hasChildren

     if (child.children) {
      let sonArr = child.children;
      for (let n = 0; n < sonArr.length; n++) {
       if (sonArr[n].name === name) {
        thirdObj = sonArr[n];
        hasChildren = true;
        return hasChildren;
       }
      }
     }
     return hasChildren
    })[0];

    if(thirdObj && childObj){
     currentPathArr = [
      {
       title: '首页',
       path: '/home',
       name: 'home_index'
      },
      {
       title: currentPathObj.title,
       path: '',
       name: currentPathObj.name
      },
      {
       title: childObj.title,
       path: '',    //设为空是因为此二级菜单没有实际页面且用于面包屑组件显示,path为空的将不可单击
       name: childObj.name
      },
      {
       title: thirdObj.title,
       path: currentPathObj.path + '/' + childObj.path + '/' + thirdObj.path,
       name: thirdObj.name
      }
     ];
    }
    
   }
   
  }
 }
 
 vm.$store.commit('setCurrentPath', currentPathArr);
 return currentPathArr;
};

第三步:建立三级页面test-child.vue,testcaca.vue和三级路由的容器组件artical-publish-center.vue
artical-publish-center.vue结构如下图: 要有<rout-view>标签

Vue iview-admin框架二级菜单改为三级菜单的方法

其他两个三级页面vue随便写了:

Vue iview-admin框架二级菜单改为三级菜单的方法

第四步:到这里,容器可以实现期待已久三级菜单了,^_^. 在router里添加三级页面路由,router文件夹下router.js中:
加到appRouter中吧,可以放到title: '组件'的children数组中:

{
    path: 'artical-publish',
    title: '用户配置',
    name: 'artical-publish',
    icon: 'compose',
    component: () => import('@/views/test/artical-publish-center.vue'), //引用三级页面的中间容器层
    children:[
     {
      path: 'testcaca',
      icon: 'ios-pause',
      name: 'testcaca',
      title: 'test4',
      component: () => import('@/views/test/testcaca.vue')
     },
     {
      path: 'test-child',
      icon: 'ios-pause',
      name: 'test-child',
      title: 'test-child',
      component: () => import('@/views/test/test-child.vue')
     }
    ]
   }

最后保存,运行你的项目,看下三级菜单出来了吧:

Vue iview-admin框架二级菜单改为三级菜单的方法

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

Javascript 相关文章推荐
JavaScript之appendChild、insertBefore和insertAfter使用说明
Dec 30 Javascript
设置jsf的选择框h:selectOneMenu为不可编辑状态的方法
Jan 07 Javascript
关于js数组去重的问题小结
Jan 24 Javascript
jQuery中addClass()方法用法实例
Jan 05 Javascript
jQuery使用CSS()方法给指定元素同时设置多个样式
Mar 26 Javascript
jquery图片切换实例分析
Apr 15 Javascript
js实现页面跳转的五种方法推荐
Mar 10 Javascript
基于Vuejs和Element的注册插件的编写方法
Jul 03 Javascript
Node.js服务器开启Gzip压缩教程
Aug 11 Javascript
vue最简单的前后端交互示例详解
Oct 11 Javascript
React降级配置及Ant Design配置详解
Dec 27 Javascript
Node.js API详解之 util模块用法实例分析
May 09 Javascript
解析vue data不可以使用箭头函数问题
Jul 03 #Javascript
详解Vue SPA项目优化小记
Jul 03 #Javascript
jQuery实现表单动态添加与删除数据操作示例
Jul 03 #jQuery
JS实现显示当前日期的实例代码
Jul 03 #Javascript
jQuery实现获取form表单内容及绑定数据到form表单操作分析
Jul 03 #jQuery
vue 设置路由的登录权限的方法
Jul 03 #Javascript
jQuery阻止事件冒泡实例分析
Jul 03 #jQuery
You might like
PHP编程网上资源导航
2006/10/09 PHP
PHP数据库开发知多少
2006/10/09 PHP
Discuz7.2版的faq.php SQL注入漏洞分析
2014/08/06 PHP
centos7上编译安装php7以php-fpm方式连接apache
2018/11/08 PHP
常用的javascript function代码
2008/05/23 Javascript
别了 JavaScript中的isXX系列
2012/08/01 Javascript
Extjs4中Form的使用之本地hiddenfield
2013/11/26 Javascript
JS冒泡事件的快速解决方法
2013/12/16 Javascript
js加入收藏以及使用Jquery更改透明度
2014/01/26 Javascript
jquery 隐藏与显示tr标签示例代码
2014/06/06 Javascript
jQuery文本框得到与失去焦点动态改变样式效果
2016/09/08 Javascript
ajax分页效果(bootstrap模态框)
2017/01/23 Javascript
js正则表达式验证密码强度【推荐】
2017/03/03 Javascript
整理关于Bootstrap列表组的慕课笔记
2017/03/29 Javascript
JavaScript实现购物车基本功能
2017/07/21 Javascript
基于复选框demo(分享)
2017/09/27 Javascript
JS实现的检验身份证格式并输出出生日期,年龄,性别,出生地示例
2019/05/17 Javascript
解决vue打包后刷新页面报错:Unexpected token
2019/08/27 Javascript
序列化模块json代码实例详解
2020/03/03 Javascript
[48:00]完美世界DOTA2联赛循环赛 Forest vs Inki BO2第二场 11.04
2020/11/04 DOTA
python编程实现随机生成多个椭圆实例代码
2018/01/03 Python
python贪婪匹配以及多行匹配的实例讲解
2018/04/19 Python
python selenium 对浏览器标签页进行关闭和切换的方法
2018/05/21 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
2020/02/22 Python
Python如何实现线程间通信
2020/07/30 Python
美国二手奢侈品寄售网站:TheRealReal
2016/10/29 全球购物
世界闻名的衬衫制造商:Savile Row Company
2018/07/30 全球购物
美国单身专业人士在线约会网站:EliteSingles
2019/03/19 全球购物
Book Depository美国:全球领先的专业网上书店之一
2019/08/14 全球购物
Emma Bridgewater官网:英国餐具制造商
2019/11/24 全球购物
俄罗斯茶和咖啡网上商店:Tea.ru
2021/01/26 全球购物
服装电子商务创业计划书
2014/01/30 职场文书
红色电影观后感
2015/06/18 职场文书
《雪域豹影》读后感:父爱的伟大
2019/12/23 职场文书
MySQL 自定义变量的概念及特点
2021/05/13 MySQL
MySQL创建管理RANGE分区
2022/04/13 MySQL