antdv & ant-design-vue-jeecg 顶部一级菜单,左侧导航二三级菜单。

1 篇文章 0 订阅

先上效果图:

需求

在顶部导航栏中点击首页,左侧导航栏中展示所有菜单。点击顶部其他菜单,左侧导航栏展示其子节点。

根据框架源码修改代码

看过antdv源码的同学应该都清楚,针对需求我们要对框架中的 GlobalLayout.vue 和 GlobalHeader.vue 两个文件中进行切入操作。

(这里展示的是比较笨的办法。最简单的是使用框架自带的vuex,在点击顶部一级导航时通过dispatch->commit保存子节点内容,然后在GlobalLayout中“computed”vuex子节点内容,watch页面展示变量,从而更新侧边导航内容)

确保layout模式

首先要明确的是,我们是在导航模式为“侧边栏导航”的选项下增加新功能。需要确保“src/views”目录下的 defaultSetting.js 中layout配置为: “layout: 'sidemenu'” 。

修改GlobalHeader.vue

打开 src\components\page\GlobalHeader.vue 文件,在 "mode === 'sidemenu'" 的div区域中增加 “顶部导航栏” 这里用到的还是框架自带的组件,但是会进行一些自定义改动。

图片中代码块1的组件TopMenu是这次要添加的顶部导航栏,代码块2是TopMenu参考的源组件。

记得在 “components” 属性 中引入 TopMenu 组件。

<top-menu 
    mode="horizontal" 
    :menu="menus" 
    :theme="theme" 
    @updateMenuTitle="handleUpdateMenuTitle"
    @topMenuItemInfo="topMenuItemInfo"
/>

在TopMenu组件中新增的 “topMenuItemInfo” 方法,用于将一级菜单的节点信息由 GlobalHeader 传递到 GlobalLayout 中的侧边导航栏。

// 将菜单信息自TopMenu组件经GlobalHeader向GlobalLayout传递。
topMenuItemInfo (val) {
    this.$emit('topMenuItemInfoToGlobalLayout', val);
}

- TopMenu组件是根据SMenu组件自定义修改而来。(文件目录自己定义,这里仅记录代码部分)

新建TopMenu.js

我们直接复制SMenu.js文件内容并生成新文件命名名为TopMenu.js。(记得修改参数name为“TopMenu”)

因为顶部导航栏只显示一级导航,所以仅对Menu组件中渲染MenuItem子节点做修改即可。使其能够只渲染一级导航。

修改TopMenu.js --> renderItem 方法,使其不需要对二三级子节点渲染。
renderItem (menu) {
    if (!menu.hidden) {
        return this.renderMenuItem(menu);
    }
    return null
}
接下来修改 renderMenuItem 方法,因为具体渲染逻辑都在这里。

首先涉及到重复判断赋值,修改const常量tag为let变量。因为要根据导航属性判断是否拥有子节点,如果拥有子节点则渲染为a标签。

修改为a标签后,需要对我们的子节点内容做操作。因为组件所在的GlobalHeader还需要将子节点内容都传递给GlobalLayout中的侧边导航栏用于展示。所以我们还需要重写该方法的返回代码。

新增如下代码。这里 $emit:topMenuItemInfo 的内容就是向上发送所点击节点的详情信息。


renderMenuItem 方法 完整代码如下:

renderMenuItem(menu) {
    const target = menu.meta.target || null
    let tag = (target && 'a') || 'router-link'
    if (menu.children && !menu.alwaysShow) {
        tag = 'a';
    }
    let props = { to: { name: menu.name } }
    if (menu.route && menu.route === '0') {
        props = { to: { path: menu.path } }
    }
    const attrs = { href: menu.path, target: menu.meta.target }
    if (menu.children && menu.alwaysShow) {
        // 把有子菜单的 并且 父菜单是要隐藏子菜单的
        // 都给子菜单增加一个 hidden 属性
        // 用来给刷新页面时, selectedKeys 做控制用
        menu.children.forEach((item) => {
            item.meta = Object.assign(item.meta, { hidden: true })
        })
    }
    const on = {
        click: () => {
            this.$emit('topMenuItemInfo', menu);
        },
    }
    let tempComponent;
    if (menu.children && !menu.alwaysShow) {
        tempComponent = (
            <Item {...{ key: menu.path }}>
                 <tag  {...{ on: on }} style="color: #fff;">
                     {this.renderIcon(menu.meta.icon)}
                     <span>{menu.meta.title}</span>
                 </tag>
            </Item>
        );
    } else {
        tempComponent = (
            <Item {...{ key: menu.path }} {...{on: on }}>
                <tag {...{ props, attrs }} style="color: #fff;">
                    {this.renderIcon(menu.meta.icon)}
                    <span>{menu.meta.title}</span>
                </tag>
            </Item>
        );
    }
    return ( tempComponent )
}
主体render的修改

根据需求,还需在主体render函数中增加自定义样式。

这里设置的width会隐藏超出显示区域的节点。以"..."代替,并采用SubMenu的方式进行展示。可能会遇到背景与文字颜色冲突的情况(全部都是同色),解决办法是重写Menu组件样式即可。

return (
    <Menu 
        style="display: inline-block; background: #1890FF; border: 0px; width: 790px; color: #fff;"
        vModel={this.selectedKeys} 
        {...{ props, on: on }}
    >
        {menuTree}
    </Menu>
)
// 超出隐藏部分SubMenu样式
.ant-menu-submenu > .ant-menu {
    background-color: #1890FF;
}

目前,已经完成了对顶部导航仅显示一级菜单的工作。

修改GlobalLayout.vue

打开 src\components\page\GlobalLayout.vue 文件。此文件为总layout布局文件,其中包含GlobalHeader组件。

在GlobalHeader组件中新增方法 “@topMenuItemInfoToGlobalLayout="topMenuItemInfo" ”,用于接收组件内容。并在data中增加 “topMenus” 属性,初始值为空数组。

接下来完善 topMenuItemInfo 方法,方法中明确展示逻辑。侧边导航是通过menus来展示的。

// 将指定的菜单子节点写入到左侧菜单栏中
topMenuItemInfo (menuItem) {
    // 这里的判断结构自行处理
    if (menuItem.meta.title !== '首页') {   
        this.menus = menuItem.children;    // 顶部一级节点的子节点
    } else {
        this.menus = this.permissionMenuList; // 展示最初的初始化路由
    }
}

注意:上图中GlobalHeader组件的menus参数为topMenus,而topMenuItemInfo方法中赋值的却是menus。

我们要将顶部导航和侧边导航源数据分开,避免因为赋值导致展示错乱。

到这里就完事了!

topMenus 的导航数据就自己处理吧!

希望大家抽空仔细阅读框架源码,提升编码水平和架构能力。

参考:jeecg前端部分,antd pro vue,前端菜单改成顶部一级左右二三级菜单,jeecg是在antd基础更改的,所以antd-design-vue菜单一二级更改类似_ant design vue实现根据路由生成左侧为一级菜单,顶部为二级菜单_Funny_genius_cai的博客-CSDN博客Vue + ElementUI 后台管理系统实现顶部一级菜单栏,左侧多级菜单栏(二级、三级等)_顶部菜单与左侧菜单vue_无解的菜鸟晖的博客-CSDN博客

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值