zoukankan      html  css  js  c++  java
  • Vue+abp增加三级菜单


    title: "Vue+abp增加三级菜单"
    publishDate: 2019-12-26 17:28:38 +0800
    date: 2019-12-26 17:28:38 +0800
    categories: Vue+abp增加三级菜单
    position: problem

    原生vue版的abp只支持2级菜单,项目需要增加成3级菜单,一番搜索。成果如下


    增加3级菜单显示

    修改components->shrinkable-menu->components->sidebarMenu文件,增加一级菜单,并增加两个方法hasChildren和getChildren,避免html因为没有children属性报错

    <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<=0" :name="item.children[0].name" :key="item.name">
                    <!-- <Icon :type="item.icon" :size="iconSize"></Icon> -->
                    <span class="iconfont">{{item.icon}}</span>
                    <span>{{ itemTitle(item) }}</span>
                </MenuItem>
                <Submenu v-if="item.children.length > 0&&!item.meta.hidden" :name="item.name" :key="item.name">
                    <template slot="title">
                        <i class="iconfont" v-html="item.icon"></i>
                        <span >{{ itemTitle(item) }}</span>
                    </template>
                    <template v-for="child in item.children">
                        <MenuItem v-if="!hasChildren(child)&&!child.meta.hidden" :name="child.name" :key="child.name"> 
                            <i class="iconfont" v-html="child.icon"></i>                       
                            <span> {{L(child.meta.title) }}</span>
                        </MenuItem>
                        <Submenu v-if="hasChildren(child)&&!child.meta.hidden" :name="child.name" :key="child.name">
                            <template slot="title">
                                <i class="iconfont" v-html="child.icon"></i>
                                <span >{{ itemTitle(child) }}</span>
                            </template>
                            <template v-for="ss in child.children">
                                <MenuItem v-if="!hasChildren(ss)&&!ss.meta.hidden" :name="ss.name" :key="ss.name"> 
                                    <i class="iconfont" v-html="ss.icon"></i>                       
                                    <span> {{L(ss.meta.title) }}</span>
                                </MenuItem>
                            </template>
                        </Submenu>
                    </template>
                </Submenu>
            </template>
        </Menu>
    </template>
    <script lang="ts">
        hasChildren(item:any){
            return !!item.children&&item.children.length>0
        }
        getChildren(item:any){
            return item.children;
        }
    </script>
    

    修改显示路由方法

    就是显示图上这个
    显示路由
    这个方法在lib->util.ts文件中,我是抄的Vue iview-admin模板二级菜单改为三级菜单,根据abp做了一些调整,修改setCurrentPath方法如下:

      setCurrentPath(vm: Vue, name?: string) {
        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 = [
            {
              meta: {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 = [
            {
              meta: {title: util.handleTitle(
                vm,
                util.getRouterObjByName(vm.$store.state.app.routers, "home_index")
              )},
              path: "/home",
              name: "home_index"
            },
            {
              meta: {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 = [
              {
                    meta: { title: "HomePage" },
                    path: "main/home",
                    name: "home"
              }
            ];
          } else if (
            currentPathObj.children.length <= 1 &&
            currentPathObj.name !== "home"
          ) {
            currentPathArr = [
              {
                    meta: { title: "HomePage" },
                    path: "main/home",
                    name: "home"
              },
              {
                meta: {title: currentPathObj.meta.title},
                path: "",
                name: name
              }
            ];
          } else {
            //如果是三级页面按钮,则在二级按钮数组中找不到这个按钮名称
            //需要二级页面下可能出现三级子菜单的情况逻辑加入
            let childObj = currentPathObj.children.filter(child => {
              return child.name === name;
            })[0];
            //二级页面
            if (childObj) {
              currentPathArr = [
                {
                    meta: { title: "HomePage" },
                    path: "main/home",
                    name: "home"
                },
                {
                  meta: {title: currentPathObj.meta.title},
                  path: "",
                  name: ""
                },
                {
                  meta: {title: childObj.meta.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 = [
                  {
                    meta: { title: "HomePage" },
                    path: "main/home",
                    name: "home"
                  },
                  {
                    meta: {title: currentPathObj.meta.title},
                    path: "",
                    name: ""
                  },
                  {
                    meta: {title: childObj.meta.title},
                    path: "", //设为空是因为此二级菜单没有实际页面且用于面包屑组件显示,path为空的将不可单击
                    name: ""
                  },
                  {
                    meta: {title: thirdObj.meta.title},
                    path:
                      currentPathObj.path +
                      "/" +
                      childObj.path +
                      "/" +
                      thirdObj.path,
                    name: thirdObj.name
                  }
                ];
              }
            }
          }
        }
        vm.$store.commit("app/setCurrentPath", currentPathArr);
        return currentPathArr;
      }
    

    修改根据菜单权限加载菜单

    如果不修改加载权限,则第三级菜单无法用权限控制,第二级菜单也必须定义权限才能显示。如果第二级菜单只是目录,第三级菜单都没有权限,那么第二级目录是不应该显示出来的。
    在store->modules->app.ts中修改updateMenulist方法如下:

    updateMenulist(state: AppState) {
        let menuList: Array<Router> = [];
        [...appRouters,...organizeRouters,...labRouters,...labcheckRouters,
            ...devRouters,...labreportRouters,...appraiseRouters].forEach((item, index) => {
            if (item.permission !== undefined) {
                Util.addHasPermissionChileMenu(item);
                if(item.children&&item.children.length>0){
                    menuList.push(item);
                }
                // let hasPermissionMenuArr: Array<Router> = [];
                // hasPermissionMenuArr = item.children.filter(child => {
                //     if (child.permission !== undefined) {
                //         if (Util.abp.auth.hasPermission(child.permission)) {
                //             return child;
                //         }
                //     } else {
                //         return child;
                //     }
                // });
                // if (hasPermissionMenuArr.length > 0) {
                //     item.children = hasPermissionMenuArr;
                //     menuList.push(item);
                // }
            } else {
                if (item.children.length === 1) {
                    menuList.push(item);
                } else {
                    let len = menuList.push(item);
                    let childrenArr = [];
                    childrenArr = item.children.filter(child => {
                        return child;
                    });
                    let handledItem = JSON.parse(JSON.stringify(menuList[len - 1]));
                    handledItem.children = childrenArr;
                    menuList.splice(len - 1, 1, handledItem);
                }
            }
        });
        state.menuList = menuList;
    }
    

    在lib->util文件中,增加方法如下:

    addHasPermissionChileMenu(item:any){
        let that=this;
        let hasPermissionMenuArr: Array<Router> = [];
        if(!item.children){
            return;
        }
        hasPermissionMenuArr = item.children.filter(child => {  
            let isFather=!!child.children;
            that.addHasPermissionChileMenu(child);
            let hasChildren=!!child.children
            if (isFather&&!hasChildren) {
                return false;
            }
    
            if (child.permission !== undefined) {
                if (that.abp.auth.hasPermission(child.permission)) {
                    return child;
                }
            } else {
                return child;
            }
        });
        if (hasPermissionMenuArr.length > 0) {
            item.children = hasPermissionMenuArr;
        }else{
            item.children=null;
        }
    }
    

    增加三级菜单路由

    在component目录中增加一个显示三级菜单内容的容器three-leve-container.vue

    <template>
    <div>
      <router-view></router-view>
    </div>
    
    </template>
    
    <script lang="ts">
    import { Component, Vue, Inject } from "vue-property-decorator";
    import ViewUI from "view-design";
    import AbpBase from "../lib/abpbase";
    import util from "../lib/util";
    @Component({
      components: {}
    })
    export default class ThreeLeveContainer extends AbpBase {
          
    }
    </script>
    
    <style>
    </style>
    

    现在可以修改你的菜单定义,在二级菜单下像第一级菜单下增加二级菜单一样增加三级菜单了,二级菜单的权限可以是undefined,二级菜单的component要定义成刚才增加的路由组件,这样不需要在后端定义具体的权限,自动根据三级菜单的权限决定是否显示二级菜单。

      {
        path: "/menu1",
        name: "menu1",
        permission: "",
        meta: { title: "menu1" },
        icon: "&#xe68a;",
        component: main,
        children: [
          {
            path: "menu2",
            permission: undefined,
            meta: { title: "menu2" },
            name: "menu2",
            component:() => import("../components/three-leve-container.vue"),
            children: [
            {
                path: "menu3",
                permission: "menu3",
                meta: { title: "menu3" },
                name: "menu3",
                component: () =>
                import("../views/xxxx.vue")
            }
            ]
          }]
      }
    

    参考资料

  • 相关阅读:
    搜索回车跳转页面
    登录验证码
    【排序算法】排序算法之插入排序
    PAT 乙级 1044 火星数字 (20 分)
    PAT 甲级 1035 Password (20 分)
    PAT 甲级 1041 Be Unique (20 分)
    PAT 甲级 1054 The Dominant Color (20 分)
    PAT 甲级 1027 Colors in Mars (20 分)
    PAT 甲级 1083 List Grades (25 分)
    PAT 甲级 1005 Spell It Right (20 分)
  • 原文地址:https://www.cnblogs.com/missile/p/12103875.html
Copyright © 2011-2022 走看看