您的当前位置:首页正文

关于Vueiview-admin框架二级菜单改为三级菜单的方法

2020-11-27 来源:筏尚旅游网
这篇文章主要介绍了Vue iview-admin框架二级菜单改为三级菜单的方法,内容挺不错的,现在分享给大家,也给大家做个参考。

最近在用 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')
 }
 ]
 }

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

显示全文