• vue3 antd多级动态菜单(二)后台管理系统(两种方法过滤有无子菜单children)


    相关文章推送(供参考)

    场景复现

    ⚡上期文章⚡中,我们简单的实现了多级动态菜单,在它的基础上,我们可以用v-for循环嵌套很多层的子菜单,但在实际开发中,大概也只会用到 三级菜单,具体的内容呈现会放在页面当中,无需过多的细分。但是,上期的代码显然存在不足——缺少 有无children子菜单 的判断

    简单来说,在不判断是否有children的情况下,一级菜单内部有两个子菜单(也可称为二级菜单),倘若需要实现多个一级菜单,有的一级菜单内部是有二级菜单的,而有的一级菜单内部是没有二级菜单的。如果我们不对子菜单的有无进行判断,就会导致每个一级菜单的内部都会默认循环有两个二级菜单

    • 解决的方式可以是放弃循环单独实现这一行一级菜单,但是你又会涉及到它的排序问题(如果它不参与循环,那它的位置应该按照先后顺序放在在循环体的中间,还是放在循环体的外面),而不采用循环很显然是一个不明智的选择,所以这个方法直接pass掉。
    • 解决方式也可以是对有无children进行判断根据条件筛选,最后实现需求

    本期文章将详细介绍比较好用的两种方法:
    👇👇👇👇👇👇👇👇👇👇👇👇👇👇

    用`hasChildren与noChildren函数过滤
    用v-if v-else判断有无children(推荐)
    两种方法都差不多,简洁快速的方式可选择②。

    实现效果

    上期文章简单实现效果👇👇👇
    在这里插入图片描述
    本期文章完善后的实现效果👇👇👇
    在这里插入图片描述
    是不是完美了许多,下面具体介绍两种解决方案。

    解决方法

    文章使用的组件库为 ant design vue 具体使用方法(点击跳转查看)

    hasChildren与noChilren函数过滤

    代码图片(含注释)
    在这里插入图片描述
    源码:(layout布局中的slider部分)【记得引入menu】

    <a-layout-sider v-model:collapsed="collapsed" collapsible>
          <div class="logo" />
          <a-menu v-model:selectedKeys="selectedKeys" v-model:openKeys="openKeys"  theme="dark" mode="inline">
            
    					<a-sub-menu :key="item.id" v-for="item of hasChildren()">
    						<template #title>
                                <Icon :icon="item.iconClass">Icon>
    							<span v-if="item.children !== null">{{item.authName}}span>
    							{item.authName}} -->
    						template>
    						
    						<a-menu-item v-for="sub of item.children" :key="sub.id" >
    							<router-link :to="'/' + sub.path">
    								
    								<span>{{sub.authName}}span>
    							router-link>
    						a-menu-item>
    					a-sub-menu>
                            <a-menu-item :index="item.path" v-for="item of noChildren()" :key="item.id" >
    							<router-link :to="'/' + item.path">
    								<Icon :icon="item.iconClass" />
    								<span>{{item.authName}}span>
    							router-link>
    						a-menu-item>
          a-menu>
    a-layout-sider>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    代码图片(含注释)
    在这里插入图片描述
    源码(script setup中的两个过滤函数)

    const noChildren = () => {
      return menu.filter((item) => !item.children); 
    }
    noChildren()
    const hasChildren = () => {
      return menu.filter((item) => item.children);
    }
    hasChildren()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    实现效果
    在这里插入图片描述

    v-if v-else判断有无children【推荐】🔥

    推荐理由

    • 相比第一种方法,更加简洁,省去两个方法。
    • 采用vue原生语法中的v-ifv-else,简单直接地实现效果。

    代码图片(含注释)
    在这里插入图片描述
    (代码按需添加即可,这里就不附加源码了)
    实现效果
    在这里插入图片描述

    两种方法公用代码

    router.ts部分源码:

        {
            path: "/home",
            name: "Home",
            component: () => import("../views/Home.vue"),
            children: [
                {
                    path: '/newStudent/newStudentArticle',
                    component: () => import("../views/newStudent/newStudnetArticle/newStudent_article.vue"),
                    meta: {
                        routerName:["新生2022", "新生板块文章"]
                    }
                },
                {
                    path: '/newStudent/newStudentDiskArea',
                    component: () => import("../views/newStudent/diskArea/diskArea.vue"),
                    meta: {
                        routerName:["新生2022", "新生板块磁片区"]
                    }
                },
                {
                    path:'/count',
                    component: () => import("../views/countDown/count.vue"),
                    meta:{
                        routerName:["默认倒计时"]
                    }
                },
            ]
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    menu.ts代码图片:
    在这里插入图片描述
    menu.ts源码:

    const menus = [
        /* eslint-disable */
        {
          "id": 100,
          "authName": "新生2022",
          "iconClass": "UserOutlined",
          "path": "newStudent",
          "children": [{
              "id": 101,
              "authName": "新生文章",
              "iconClass": "Reading",
              "path": "newStudent/newStudentArticle",
              "children": []
          }, {
              "id": 102,
              "authName": "磁片区",
              "iconClass": "Magnet",
              "path": "newStudent/newStudentDiskArea",
              "children": []
          },]
        },
        {
          "id":110,
          "authName":"默认倒计时",
          "iconClass":"HistoryOutlined",
          "path":"count",
        },
      ]
      
      export default menus
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    sunmmary

    • 以上就是对多级动态菜单的优化实现。不管是子菜单的筛选判断,还是项目文件的功能化分化,相较与上期的简单实现都有很大提升。

    下期预告

    搜索栏的筛选功能

    axios请求

    导航栏的高质量实现非常重要,如果文章对大家有帮助或者价值,建议点赞收藏,方便后续查看

  • 相关阅读:
    【Java+SSM】电影院管理系统(电影院选座系统、在线电影购票系统)
    【SpringBoot整合NoSql】-----MongoDB篇
    vue2时间处理插件——dayjs
    我国蜂窝物联网模组产业发展情况如何
    volatile-两大特性(可见性、有序性)、内存屏障
    jsp EL表达式获取servlet中的数据
    安全防御第三次作业
    MySQL update 是锁行还是锁表?
    配置ftp及java链接上传文件到ftp
    SQL常用语句大全
  • 原文地址:https://blog.csdn.net/XSL_HR/article/details/127827748