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下字符串连接的性能
Mar 05 Javascript
extjs4 treepanel动态改变行高度示例
Dec 17 Javascript
基于Javascript实现返回顶部按钮
Feb 29 Javascript
JavaScript利用HTML DOM进行文档操作的方法
Mar 28 Javascript
js的OOP继承实现(必看篇)
Feb 18 Javascript
详解使用webpack打包编写一个vue-toast插件
Nov 08 Javascript
关于HTTP传输中gzip压缩的秘密探索分析
Jan 12 Javascript
JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法示例
Jul 27 Javascript
原生JS+HTML5实现的可调节写字板功能示例
Aug 30 Javascript
JS中自定义事件的使用与触发操作实例分析
Nov 01 Javascript
Javascript ParentNode和ChildNode接口原理解析
Mar 16 Javascript
不依任何赖第三方,单纯用vue实现Tree 树形控件的案例
Sep 21 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 和 MySQL 开发的 8 个技巧
2006/10/09 PHP
支持生僻字且自动识别utf-8编码的php汉字转拼音类
2014/06/27 PHP
PHP中array_map与array_column之间的关系分析
2014/08/19 PHP
YII2框架中使用yii.js实现的post请求
2017/04/09 PHP
PHP实现在windows下配置sendmail并通过mail()函数发送邮件的方法
2017/06/20 PHP
IE与FireFox的兼容性问题分析
2007/04/22 Javascript
《JavaScript高级程序设计》阅读笔记(一) ECMAScript基础
2012/02/27 Javascript
js获取url中指定参数值的示例代码
2013/12/14 Javascript
javascript实现的弹出层背景置灰-模拟(easyui dialog)
2013/12/27 Javascript
JavaScript学习笔记之JS对象
2015/01/22 Javascript
javascript与css3动画结合使用小结
2015/03/11 Javascript
js简单实现点击左右运动的方法
2015/04/10 Javascript
JavaScript模块规范之AMD规范和CMD规范
2015/10/27 Javascript
JS简单生成两个数字之间随机数的方法
2016/08/03 Javascript
实例解析Array和String方法
2016/12/14 Javascript
jquery对table做排序操作的实例演示
2017/08/10 jQuery
微信小程序实现默认第一个选中变色效果
2018/07/17 Javascript
JS正则表达式验证密码强度
2020/03/18 Javascript
vue实现简易图片左右旋转,上一张,下一张组件案例
2020/07/31 Javascript
基于javascript的无缝滚动动画实现2
2020/08/07 Javascript
Python使用Socket(Https)Post登录百度的实现代码
2012/05/18 Python
详细讲解Python中的文件I/O操作
2015/05/24 Python
Python实现翻转数组功能示例
2018/01/12 Python
Python实现找出数组中第2大数字的方法示例
2018/03/26 Python
用xpath获取指定标签下的所有text的实例
2019/01/02 Python
pytorch 加载(.pth)格式的模型实例
2019/08/20 Python
keras导入weights方式
2020/06/12 Python
利用CSS3实现动态的二级三级菜单效果实例源码
2017/01/04 HTML / CSS
英国排名第一的最新设计师品牌手表独立零售商:TIC Watches
2016/09/24 全球购物
送给他或她的礼物:FUN.com
2018/08/17 全球购物
常用UNIX 命令(Linux的常用命令)
2015/12/26 面试题
同学会主持词
2014/03/18 职场文书
关于感恩的演讲稿500字
2014/08/26 职场文书
2014年保育员个人工作总结
2014/12/02 职场文书
2014年学生党支部工作总结
2014/12/20 职场文书
使用react-virtualized实现图片动态高度长列表的问题
2021/05/28 Javascript