最近在用 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\') } ] }
最后保存,运行你的项目,看下三级菜单出来了吧:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
© 版权声明
THE END
暂无评论内容