Element-ui 之 多级路由导航(已解决点击收起展开按钮时的文字不隐藏以及文字卡顿现象)2022-04-12已更新vue-fragment的bug问题


效果及代码

  • 话不多说,先看效果!

在这里插入图片描述

  • 上代码:
  1. 首先这是封装好的导航组件;
<template>
    <fragment class="sidebar-item"> // 这个组件时通过npm install 下载的空标签库,用作解决点击收起时文字不隐藏的问题;下文会做详细解析
        <template v-for="(item) in menu">
            <!-- 最后一级菜单 -->
            <el-menu-item
                    v-if="!item.children"
                    :key="item.path"
                    :index="item.path"
                    @click="addTab(item.path, item.title)"
            >
                <i :class="item.icon"></i>
                <span slot="title">{{ item.title }}</span>
            </el-menu-item>

            <!-- 此菜单下还有子菜单 -->
            <el-submenu
                    v-if="item.children"
                    :key="item.path"
                    :index="item.path"
            >
                <template slot="title">
                    <i :class="item.icon"></i>
                    <span> {{ item.title }}</span>
                </template>
                <!-- 递归 -->
                <sidebar-item
                        :menu="item.children"
                        :parent="item.path"
                />
            </el-submenu>
        </template>
    </fragment>
</template>
  1. 然后在相应的页面中调用:
<template>
    <div class="xtAside">
            <el-menu class="el-menu-vertical-demo" :default-active="$route.path" :collapse="isCollapse" router >
                <sidebar-item :menu="navs" /> // 在这里调用封装好的导航组件
            </el-menu>
    </div>
</template>

<script>
	import navs from '@/utils/navs' // 引用路由导航信息
	export default {
        name: "XtAside",
        components: {
            SidebarItem: () => import('./SidebarItem.vue'), // 懒加载组件
        },
    }
</script>

<style lang="scss" scoped>
    .xtAside{
        height: 100%;
        .el-menu{
            border: none;
            height: 100%;
            &:not(.el-menu--collapse) { // 这里是解决点击收起展开按钮时的文字卡顿现象
                width: 200px;
            }
        }
    }
</style>  
  1. 导航路由信息:
// 路由懒加载
const Home = () => import('@/pages/home/Home.vue');
// 采购管理
const MyContract = () => import('@/pages/procurement/contract/MyContract.vue');
const MyOrder = () => import('@/pages/procurement/order/MyOrder.vue');
const MyShipments = () => import('@/pages/procurement/shipments/MyShipments.vue');
// 质量管理
// 账款管理
const FinancialAccounts = () => import('@/pages/valueInAccount/account/FinancialAccounts.vue');
const BusinessAccounts = () => import('@/pages/valueInAccount/account/BusinessAccounts.vue');
const MyInvoice = () => import('@/pages/valueInAccount/invoice/MyInvoice.vue');
const MyPayment = () => import('@/pages/valueInAccount/payment/MyPayment.vue');
const MyStatement = () => import('@/pages/valueInAccount/statement/MyStatement.vue');
export default [
    {
        id: 1,
        path: '/procurement',
        comm: Home,
        title: '采购管理',
        icon: 'el-icon-location',
        children: [
            { id: 11, title: '采购管理1', icon: 'el-icon-menu', path: '/procurement/myContract', comm: MyContract },
            { id: 12, title: '采购管理2', icon: 'el-icon-menu', path: '/procurement/myOrder', comm: MyOrder },
            { id: 13, title: '采购管理3', icon: 'el-icon-menu', path: '/procurement/myShipments', comm: MyShipments },
        ]
    },
    {
        id: 2,
        path: '/quality',
        comm: Home,
        title: '质量管理',
        icon: 'el-icon-location',
        children: [
            { id: 11, title: '质量管理1', icon: 'el-icon-menu', path: '/quality/myContract1', comm: MyContract },
            { id: 12, title: '质量管理2', icon: 'el-icon-menu', path: '/quality/myOrder2', comm: MyOrder },
            { id: 13, title: '质量管理3', icon: 'el-icon-menu', path: '/quality/myShipments3', comm: MyShipments },
        ]
    },
    {
        id: 3,
        path: '/valueInAccount',
        comm: Home,
        title: '账款管理',
        icon: 'el-icon-location',
        children: [
            { id: 31, title: '账款管理1', icon: 'el-icon-menu', path: '/valueInAccount/myStatement', comm: MyStatement },
            { id: 32, title: '账款管理2', icon: 'el-icon-menu', path: '/valueInAccount/myInvoice', comm: MyInvoice },
            { id: 33, title: '账款管理3', icon: 'el-icon-menu', path: '/valueInAccount/myAccount', comm: FinancialAccounts, children: [
                    { id: 332, title: '账款管理3-1', icon: 'el-icon-menu', path: '/valueInAccount/myAccount/businessAccounts', comm: BusinessAccounts },
                    { id: 331, title: '账款管理3-2', icon: 'el-icon-menu', path: '/valueInAccount/myAccount/financialAccounts', comm: FinancialAccounts }
                ]
            },
            { id: 34, title: '账款管理4', icon: 'el-icon-menu', path: '/valueInAccount/myPayment', comm: MyPayment },
        ]
    }
]



代码解析

其他的都没什么好说的,最主要的两个点,也是经常问到的两个点:

问题1、点击收起时导航文字不隐藏;

  • 原因:这是因为在封装导航组件的时候,有些小伙伴在<el-menu>嵌套中使用了<div>,而<el-menu>标签本身希望里面嵌套的是<el-menu-item>,<el-submenu>,<el-menu-item-group>其中之一,
    • 如图:
      当封装导航组件使用的是div根标签时,点击收起的时候导航的文字没有隐藏的:
      在这里插入图片描述
    • 查看控制台:
      在这里插入图片描述

  • 解决方案:

这个时候我们就需要使用到一个空标签组件库vue-fragment

  1. 安装(我使用的是cnpm的安装方式安装的,其他的请自行切换安装方式):
cnpm install --save vue-fragment
  1. 在main.js文件中引入:
// main.js
import Fragment from 'vue-fragment'
Vue.use(Fragment.Plugin)
  1. 使用方法(直接在封装好的组件SidebarItem中将div标签换成fragment标签即可):
<template>
    <fragment class="sidebar-item">
<!--    <div class="sidebar-item">-->
        <template v-for="(item) in menu">
            <!-- 最后一级菜单 -->
            <el-menu-item
                    v-if="!item.children"
                    :key="item.path"
                    :index="item.path"
                    @click="addTab(item.path, item.title)"
            >
                <i :class="item.icon"></i>
                <span slot="title">{{ item.title }}</span>
            </el-menu-item>

            <!-- 此菜单下还有子菜单 -->
            <el-submenu
                    v-if="item.children"
                    :key="item.path"
                    :index="item.path"
            >
                <template slot="title">
                    <i :class="item.icon"></i>
                    <span> {{ item.title }}</span>
                </template>
                <!-- 递归 -->
                <sidebar-item
                        :menu="item.children"
                        :parent="item.path"
                />
            </el-submenu>
        </template>
<!--    </div>-->
    </fragment>
</template>

  
  

问题2:点击收起时文字会先卡一次然后再隐藏的;

在这里插入图片描述

  • 原因:样式问题;

    • 当导航展开时:在这里插入图片描述
    • 当导航隐藏时:
      在这里插入图片描述
  • 解决方案:在该组件中添加样式

<style lang="scss" scoped>
    .xtAside{
        height: 100%;
        .el-menu{
            border: none;
            height: 100%;
            &:not(.el-menu--collapse) { // 这里是解决点击收起展开按钮时的文字卡顿现象
                width: 200px;
            }

        }
    }
</style>

写在末尾

在此感谢大佬们的分享!


2022-04-12更新 vue-fragment 的 bug 问题

针对问题1,如果安装的vue-fragment有bug,比如初始化的时候不显示vue-fragment包裹的内容时:
在这里插入图片描述
此时可以考虑降低vue-fragment版本,下载指定版本,使用方法一样(亲测):
安装方式请自行切换

npm install vue-fragment@1.5.0

在这里插入图片描述
完美解决!



以上就是本文的全部内容,如有不足,望大家多多指点! 谢谢!

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhuangvi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值