| 相关文章链接 |
|---|
| vue3【列表渲染】v-for 详细介绍(vue中的“循环”) |
| vue3+ant design vue+ts实战【ant-design-vue组件库引入】🔥 |
| vue3 antd多级动态菜单(一)后台管理系统(v-for循环)🔥🔥 |
⚡上期文章⚡中,我们简单的实现了多级动态菜单,在它的基础上,我们可以用v-for循环嵌套很多层的子菜单,但在实际开发中,大概也只会用到 三级菜单,具体的内容呈现会放在页面当中,无需过多的细分。但是,上期的代码显然存在不足——缺少 有无children子菜单 的判断。
简单来说,在不判断是否有children的情况下,一级菜单内部有两个子菜单(也可称为二级菜单),倘若需要实现多个一级菜单,有的一级菜单内部是有二级菜单的,而有的一级菜单内部是没有二级菜单的。如果我们不对子菜单的有无进行判断,就会导致每个一级菜单的内部都会默认循环有两个二级菜单。
本期文章将详细介绍比较好用的两种方法:
👇👇👇👇👇👇👇👇👇👇👇👇👇👇① 用`hasChildren与noChildren函数过滤
② 用v-if v-else判断有无children(推荐)
两种方法都差不多,简洁快速的方式可选择②。
上期文章简单实现效果👇👇👇

本期文章完善后的实现效果👇👇👇

是不是完美了许多,下面具体介绍两种解决方案。
文章使用的组件库为 ant design vue 具体使用方法(点击跳转查看)
代码图片(含注释)

源码:(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>
代码图片(含注释)

源码(script setup中的两个过滤函数)
const noChildren = () => {
return menu.filter((item) => !item.children);
}
noChildren()
const hasChildren = () => {
return menu.filter((item) => item.children);
}
hasChildren()
实现效果

推荐理由
- 相比第一种方法,更加简洁,省去两个方法。
- 采用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
(导航栏的高质量实现非常重要,如果文章对大家有帮助或者价值,建议点赞收藏,方便后续查看)