vue3 antd 多级动态菜单(精修版本) 两种方法实现对children的筛选
相关文章推送(供参考)
相关文章链接 |
---|
vue3【列表渲染】v-for 详细介绍(vue中的“循环”) |
vue3+ant design vue+ts实战【ant-design-vue组件库引入】🔥 |
vue3 antd多级动态菜单(一)后台管理系统(v-for循环)🔥🔥 |
场景复现
⚡上期文章⚡中,我们简单的实现了多级动态菜单,在它的基础上,我们可以用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>
<!-- <span v-else @click="toHome()">{{item.authName}}</span> -->
</template>
<!-- 二级菜单 -->
<a-menu-item v-for="sub of item.children" :key="sub.id" >
<router-link :to="'/' + sub.path">
<!-- <a-icon :type="sub.type" /> -->
<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>
代码图片(含注释)
源码(script setup
中的两个过滤函数)
const noChildren = () => {
return menu.filter((item) => !item.children);
}
noChildren()
const hasChildren = () => {
return menu.filter((item) => item.children);
}
hasChildren()
实现效果
v-if v-else判断有无children【推荐】🔥
推荐理由
- 相比第一种方法,更加简洁,省去两个方法。
- 采用vue原生语法中的
v-if
与v-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:["默认倒计时"]
}
},
]
}
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
sunmmary
- 以上就是对多级动态菜单的优化实现。不管是子菜单的筛选判断,还是项目文件的功能化分化,相较与上期的简单实现都有很大提升。
下期预告
搜索栏的筛选功能
axios请求
(导航栏的高质量实现非常重要,如果文章对大家有帮助或者价值,建议点赞收藏,方便后续查看)