Vue iview-admin框架二级菜单改为三级菜单的方法
程序员文章站
2023-11-20 12:33:52
最近在用 iview-admin的vue后台模板,从git上下载后发现左侧导航栏最多支持到二级菜单,也发现很多童鞋在问如何实现三级菜单。在实际的应用场景中还是会出现三级菜单...
最近在用 iview-admin的vue后台模板,从git上下载后发现左侧导航栏最多支持到二级菜单,也发现很多童鞋在问如何实现三级菜单。在实际的应用场景中还是会出现三级菜单的需求的,木有其他好办法,只能自己手动改代码了。
1. 第一步:首先改写vue中的模板,修改sidebarmenu.vue文件,文件具体目录建下图:
将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随便写了:
第四步:到这里,容器可以实现期待已久三级菜单了,^_^. 在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实现自定义多选与单选的答题功能