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
jQuery 淡入淡出 png图在ie8下有黑色边框的解决方法
Mar 05 Javascript
jQuery 借助插件Lavalamp实现导航条动态美化效果
Sep 27 Javascript
jquery按回车提交数据的代码示例
Nov 05 Javascript
jquery重复提交请求的原因浅析
May 23 Javascript
使用iojs的jsdom库实现同步系统时间
Apr 20 Javascript
layui前段框架日期控件使用方法详解
May 19 Javascript
Vue2.0点击切换类名改变样式的方法
Aug 22 Javascript
jquery分页插件pagination使用教程
Oct 23 jQuery
用原生 JS 实现 innerHTML 功能实例详解
Apr 03 Javascript
Vue调用后端java接口的实例代码
Oct 28 Javascript
json_decode 索引为数字时自动排序问题解决方法
Mar 28 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实现采集程序原理和简单示例代码
2007/03/18 PHP
PHP函数常用用法小结
2010/02/08 PHP
PHP实现异步调用方法研究与分享
2011/10/27 PHP
php异常处理技术,顶级异常处理器
2012/06/13 PHP
php如何连接sql server
2015/10/16 PHP
php简单实现sql防注入的方法
2016/04/22 PHP
Paypal实现循环扣款(订阅)功能
2017/03/23 PHP
PHP依赖注入原理与用法分析
2018/08/21 PHP
JavaScript高级程序设计
2006/12/29 Javascript
JQuery的一些小应用收集
2010/03/27 Javascript
非阻塞动态加载javascript广告实现代码
2010/11/17 Javascript
jQuery lazyload 的重复加载错误以及修复方法
2010/11/19 Javascript
javascript (用setTimeout而非setInterval)
2011/12/28 Javascript
jQuery提交表单ajax查询实例代码
2012/10/07 Javascript
js遍历子节点子元素附属性及方法
2014/08/19 Javascript
javascript数组去重小结
2016/03/07 Javascript
浅谈JavaScript中的this指针和引用知识
2016/08/05 Javascript
JS简单实现无缝滚动效果实例
2016/08/24 Javascript
jQuery 全选 全不选 事件绑定的实现代码
2017/01/23 Javascript
微信小程序 支付后台java实现实例
2017/05/09 Javascript
CentOS 安装NodeJS V8.0.0的方法
2017/06/15 NodeJs
浅谈MUI框架中加载外部网页或服务器数据的方法
2018/01/31 Javascript
jQuery 实现DOM元素拖拽交换位置的实例代码
2020/07/14 jQuery
Python中pygame安装方法图文详解
2015/11/11 Python
pandas series序列转化为星期几的实例
2018/04/11 Python
Python求两个圆的交点坐标或三个圆的交点坐标方法
2018/11/07 Python
Python中遍历列表的方法总结
2019/06/27 Python
Python字典对象实现原理详解
2019/07/01 Python
python中round函数保留两位小数的方法
2020/12/04 Python
电子商务专业实习生自我鉴定
2013/09/24 职场文书
自荐信封面
2013/12/04 职场文书
入党积极分子批评与自我批评思想汇报
2014/09/14 职场文书
证券公司客户经理岗位职责
2015/04/09 职场文书
2015年秋学期教研工作总结
2015/10/14 职场文书
JavaScript利用html5新方法操作元素类名详解
2021/11/27 Javascript
springboot实现string转json json里面带数组
2022/06/16 Java/Android