• ABP实践(5)-abp前端vue框架之IView实现三级菜单(博友需要特此分享)


    为响应博友想要知道三级菜单怎么实现本篇文章先介绍三级菜单的实现,后续再分享其他部分内容

    1 修改菜单组件sidebarMenu.vue

    • 图为原代码和修改后代码比对
    • 修改前后的源码如下
    <style lang="less">
    @import "../styles/menu.less";
    </style>
    
    <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" :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 :name="child.name" :key="child.name">
                <i class="iconfont" v-html="child.icon"></i>
                <span>{{ L(child.meta.title) }}</span>
              </MenuItem>
            </template>
          </Submenu>-->
          <Submenu v-if="item.children.length > 0" :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="!isChild(child.children)" :name="child.name" :key="child.name">
                <i class="iconfont" v-html="child.icon"></i>
                <span>{{ L(child.meta.title) }}</span>
              </MenuItem>
              <Submenu v-else :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="child in child.children">
                  <MenuItem v-if="!isChild(child.children)" :name="child.name" :key="child.name">
                    <i class="iconfont" v-html="child.icon"></i>
                    <span>{{ L(child.meta.title) }}</span>
                  </MenuItem>
                </template>
              </Submenu>
            </template>
          </Submenu>
        </template>
      </Menu>
    </template>
    
    <script lang="ts">
    import { Component, Vue, Inject, Prop, Emit } from "vue-property-decorator";
    import AbpBase from "../../../lib/abpbase";
    @Component({})
    export default class SidebarMenu extends AbpBase {
      name: string = "sidebarMenu";
      @Prop({ type: Array }) menuList: Array<any>;
      @Prop({ type: Number }) iconSize: number;
      @Prop({ type: String, default: "dark" }) menuTheme: string;
      @Prop({ type: Array }) openNames: Array<string>;
      itemTitle(item: any): string {
        return this.L(item.meta.title);
      }
      @Emit("on-change")
      changeMenu(active: string) {}
      updated() {
        this.$nextTick(() => {
          if (this.$refs.sideMenu) {
            (this.$refs.sideMenu as any).updateActiveName();
          }
        });
      }
    
      isChild(item) {
        if (item && item.length > 0) {
          return true;
        } else {
          return false;
        }
      }
    }
    </script>
    
    

    2 修改路由菜单配置文件router.ts

    • 在新增的内容里有注释(第三级菜单),全部代码如下
    declare global {
        interface RouterMeta {
            title: string;
        }
        interface Router {
            path: string;
            name: string;
            icon?: string;
            permission?: string;
            meta?: RouterMeta;
            component: any;
            children?: Array<Router>;
        }
        interface System {
            import(request: string): Promise<any>
        }
        var System: System
    }
    import login from '../views/login.vue'
    import home from '../views/home/home.vue'
    import main from '../views/main.vue'
    
    export const locking = {
        path: '/locking',
        name: 'locking',
        component: () => import('../components/lockscreen/components/locking-page.vue')
    };
    export const loginRouter: Router = {
        path: '/',
        name: 'login',
        meta: {
            title: 'LogIn'
        },
        component: () => import('../views/login.vue')
    };
    export const otherRouters: Router = {
        path: '/main',
        name: 'main',
        permission: '',
        meta: { title: 'ManageMenu' },
        component: main,
        children: [
            { path: 'home', meta: { title: 'HomePage' }, name: 'home', component: () => import('../views/home/home.vue') }
        ]
    }
    export const appRouters: Array<Router> = [{
        path: '/setting',
        name: 'setting',
        permission: '',
        meta: { title: 'ManageMenu' },
        icon: '&#xe68a;',
        component: main,
        children: [
            { path: 'user', permission: 'Pages.Users', meta: { title: 'Users' }, name: 'user', component: () => import('../views/setting/user/user.vue') },
            { path: 'role', permission: 'Pages.Roles', meta: { title: 'Roles' }, name: 'role', component: () => import('../views/setting/role/role.vue') },
            { path: 'tenant', permission: 'Pages.Tenants', meta: { title: 'Tenants' }, name: 'tenant', component: () => import('../views/setting/tenant/tenant.vue') },
            { path: 'goods', permission: 'Pages.Goods', meta: { title: 'Goods' }, name: 'goods', component: () => import('../views/setting/goods/goods.vue') },
            //第三级菜单
            {
                path: '', permission: 'Pages.Goods', meta: { title: 'GoodsManage' }, name: 'goodsManage', component:()=>  import('../views/setting/goods/goods.vue'),
                children: [
                    { path: 'goods', permission: 'Pages.Goods', meta: { title: 'Goods' }, name: 'goods', component: () => import('../views/setting/goods/goods.vue') }
                ]
            }
        ]
    }]
    export const routers = [
        loginRouter,
        locking,
        ...appRouters,
        otherRouters
    ];
    
    

    到此菜单已经可以出来,但是头部面包屑展示有问题需要修改lib下的util.ts改后代码如下其中有注释面包屑字眼的为修改代码

    import Vue from 'vue';
    import appconst from './appconst'
    class Util{
        abp:any=window.abp;
        loadScript(url:string){
            var script=document.createElement('script');
            script.type="text/javascript";
            script.src=url;
            document.body.appendChild(script);
        }
        title(title:string){
            let appname=this.abp.localization.localize('AppName',appconst.localization.defaultLocalizationSourceName);
            let page=this.abp.localization.localize(title,appconst.localization.defaultLocalizationSourceName);
            window.document.title = appname+'--'+page;
        }
        inOf(arr:Array<any>, targetArr:any) {
            let res = true;
            arr.forEach(item => {
                if (targetArr.indexOf(item) < 0) {
                    res = false;
                }
            });
            return res;
        }
        oneOf(ele:any, targetArr:Array<any>) {
            if (targetArr.indexOf(ele) >= 0) {
                return true;
            } else {
                return false;
            }
        }
        showThisRoute (itAccess:any, currentAccess:any) {
            if (typeof itAccess === 'object' && Array.isArray(itAccess)) {
                return this.oneOf(currentAccess, itAccess);
            } else {
                return itAccess === currentAccess;
            }
        }
        getRouterObjByName (routers:Array<any>, name?:string):any {
            if (!name || !routers || !routers.length) {
                return null;
            }
            let routerObj = null;
            for (let item of routers) {
                if (item.name === name) {
                    return item;
                }
                routerObj = this.getRouterObjByName(item.children, name);
                if (routerObj) {
                    return routerObj;
                }
            }
            return null;
        }
        toDefaultPage (routers:Array<any>, name:string|undefined, route:any, next:any) {
            let len = routers.length;
            let i = 0;
            let notHandle = true;
            while (i < len) {
                if (routers[i].name === name && routers[i].children && routers[i].redirect === undefined) {
                    route.replace({
                        name: routers[i].children[0].name
                    });
                    notHandle = false;
                    next();
                    break;
                }
                i++;
            }
            if (notHandle) {
                next();
            }
        }
        handleTitle (vm:any, item:any) {
            if (typeof item.meta.title === 'object') {
                return vm.$t(item.title.i18n);
            } else {
                return item.meta.title;
            }
        }
        setCurrentPath  (vm:Vue, name?:string) {
            let title = '';
            let isOtherRouter = false;
            vm.$store.state.app.routers.forEach((item:any) => {
                if (item.children.length === 1) {
                    if (item.children[0].name === name) {
                        title = this.handleTitle(vm, item);
                        if (item.name === 'otherRouter') {
                            isOtherRouter = true;
                        }
                    }
                } else {
                    item.children.forEach((child:any) => {
                        if (child.name === name) {
                            title = this.handleTitle(vm, child);
                            if (item.name === 'otherRouter') {
                                isOtherRouter = true;
                            }
                        }
                    });
                }
            });
            let currentPathArr = [];
            if (name === 'home') {
                currentPathArr = [
                    {
                        meta:{title: this.handleTitle(vm, this.getRouterObjByName(vm.$store.state.app.routers, 'home'))},
                        path: 'main/home',
                        name: 'home'
                    }
                ];
            } else if (((name as string).indexOf('index') >= 0 || isOtherRouter) && name !== 'home') {
                currentPathArr = [
                    {
                        meta:{title: this.handleTitle(vm, this.getRouterObjByName(vm.$store.state.app.routers, 'home'))},
                        path: 'main/home',
                        name: 'home'
                    },
                    {
                        meta:{title: title},
                        path: '',
                        name: name
                    }
                ];
            } else {
                let currentPathObj = vm.$store.state.app.routers.filter((item:any) => {
                    if (item.children.length <= 1) {
                        return item.children[0].name === name||item.name===name;
                    } else {
                        let i = 0;
                        let childArr = item.children;
                        let len = childArr.length;
                        while (i < len) {
                            //第三级菜单面包屑
                            if(childArr[i].children&&childArr[i].children.length>0){
                                for(let children of childArr[i].children){
                                    if(children.name===name){
                                        return true;
                                    }
                                }
                            } 
                            //-------------
                            if (childArr[i].name === name) {
                                return true;
                            }
                            i++;
                        }
                        return false;
                    }
                })[0];
                if (currentPathObj.children&&currentPathObj.children.length <= 1 && currentPathObj.name === 'home') {
                    currentPathArr = [
                        {
                            meta:{title: 'HomePage'},
                            path: 'main/home',
                            name: 'home'
                        }
                    ];
                } else if (currentPathObj.children&&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:any) => {
                        //第三级菜单实现
                        if(child.children&&child.children.length>0){
                            return true;
                        }
                        //--------------------
                        return child.name === name;
                    })[0];
                    currentPathArr = [
                        {
                            meta:{title: 'HomePage'},
                            path: 'main/home',
                            name: 'home'
                        },
                        {
                            meta:{title: currentPathObj.meta.title},
                            path: '',
                            name: ''
                        },
                        {//-----第三级菜单面包屑
                            meta:{title: childObj.meta.title},
                            path: '',
                            name: childObj.name
                        }
                    ];
                    if(childObj.children&&childObj.children.length>0){
                        let tChildObj = childObj.children.filter((child:any) => {
                            return child.name === name;
                        })[0];
                        if(tChildObj){
                            let tr={
                                meta:{title: tChildObj.meta.title},
                                path: currentPathObj.path + '/' +tChildObj.path+'/'+ tChildObj.path,
                                name: name
                            }
                            currentPathArr.push(tr)
                        }
                        
                    }
                    //--------------------
                }
            }
            vm.$store.commit('app/setCurrentPath', currentPathArr);
        
            return currentPathArr;
        }
        openNewPage (vm:Vue, name:string|undefined, argu?:any, query?:any) {
            let pageOpenedList = vm.$store.state.app.pageOpenedList;
            let openedPageLen = pageOpenedList.length;
            let i = 0;
            let tagHasOpened = false;
            while (i < openedPageLen) {
                if (name === pageOpenedList[i].name) { // 页面已经打开
                    vm.$store.commit('app/pageOpenedList', {
                        index: i,
                        argu: argu,
                        query: query
                    });
                    tagHasOpened = true;
                    break;
                }
                i++;
            }
            if (!tagHasOpened) {
                let tag = vm.$store.state.app.tagsList.filter((item:any) => {
                    if (item.children) {
                        return name === item.children[0].name;
                    } else {
                        return name === item.name;
                    }
                });
                tag = tag[0];
                if (tag) {
                    tag = tag.children ? tag.children[0] : tag;
                    if (argu) {
                        tag.argu = argu;
                    }
                    if (query) {
                        tag.query = query;
                    }
                    vm.$store.commit('app/increateTag', tag);
                }
            }
            vm.$store.commit('app/setCurrentPageName', name);
        }
        fullscreenEvent (vm:Vue) {
            vm.$store.commit('app/initCachepage');
            // 权限菜单过滤相关
            vm.$store.commit('app/updateMenulist');
            // 全屏相关
        }
        extend(...args:any[]) {
            let options, name, src, srcType, copy, copyType, copyIsArray, clone,
            target = args[0] || {},
            i = 1,
            length = args.length,
            deep = false;
            if ( typeof target === 'boolean') {
                deep = target;
                target = args[i] || {};
                i++;
            }
            if ( typeof target !== 'object' && typeof target !== 'function') {
                target = {};
            }
            if ( i === length) {
                target = this;
                i--;
            }
            for ( ; i < length; i++ ) {
                if ( (options = args[i]) !== null ) {
                    for ( name in options ) {
                        src = target[name];
                        copy = options[name];
                        if ( target === copy ) {
                            continue;
                        }
                        srcType = Array.isArray(src) ? 'array': typeof src;
                        if ( deep && copy && ((copyIsArray = Array.isArray(copy)) || typeof copy === 'object')) {
                            if ( copyIsArray ) {
                                copyIsArray = false;
                                clone = src && srcType === 'array' ? src : [];
                            } else {
                                clone = src && srcType === 'object' ? src: {};
                            }
                            target[name] = this.extend(deep, clone, copy);
                        } else if ( copy !== undefined ) {
                            target[name] = copy;
                        }
                    }
                }
            }
            return target;
        }
    }
    const util=new Util();
    export default util;
    

    知道如何实现三级菜单可以考虑一下怎么实现无限级菜单(以后有时间再分享)

  • 相关阅读:
    调用外部程序主窗体做子窗体
    查看window编码
    c# 数据库更新和界面刷新的问题
    c# datagridview代码(网上的)
    winform DataGridView控件的打印
    西电ubuntu更新软件源
    C++ primer 学习笔记(2):函数
    C++ Primer 学习笔记(1)——迭代器,数组
    查询表属于哪个数据
    oracle 实用语句
  • 原文地址:https://www.cnblogs.com/wuyubing/p/12613562.html
Copyright © 2020-2023  润新知