vue3 antd多级动态菜单(一)后台管理系统(v-for循环)

本文通过Vue3和AntDesignVue构建了一个后台管理系统的多级菜单,利用v-for循环遍历路由实现动态渲染。文章详细介绍了组件的使用和代码实现,包括Menu组件和SubMenu组件的配置,以及监听openKeys的变化。同时,预告了下期将解决菜单有无children的判断问题和搜索筛选功能。
摘要由CSDN通过智能技术生成

相关文章链接
vue3【列表渲染】v-for 详细介绍(vue中的“循环”)
vue3+ant design vue+ts实战【ant-design-vue组件库引入】🔥

前言引入

一个完整的后台管理系统一定离不开各个分工的页面,其中作为门户的是登录页面,登录后的页面为主页面。顾名思义,主页面能够容纳所有的元素,实现各种跳转。主页面包括导航栏(左侧和顶部)主要内容区

👏👏👏本期文章将用v-for循环实现多级菜单栏
下期文章将分享菜单栏的优化版本,解决对children的判断。👏👏👏

场景复现

从零开始的后台管理系统,需要一个基础的Home页面,Home页面需要有完善的menu菜单。

下面是大致的实现效果:👇👇👇
在这里插入图片描述

解决方案🔥

先上源码 具体步骤后续详细说明👇👇👇
Home.vue(部分)

<script setup lang="ts">
import { defineComponent, ref, watch, reactive } from 'vue';
import type { MenuProps } from 'ant-design-vue';
import { useRouter } from 'vue-router'

    const router = useRouter();
    const list = router.getRoutes().filter(v => v.meta.isShow); // filter过滤出子路由中对页面渲染的结果
    console.log(list);

    const selectedKeys = ref<string[]>(['it.path']);
    const openKeys = ref<string[]>(['i.path']);
    const handleClick: MenuProps['onClick'] = e => {
    console.log('click', e);
};
const titleClick = (e: Event) => {
    console.log('titleClick', e);
};
    watch(
        () => openKeys,
        val => {
            console.log('openKeys', val);
        },)
</script>

<template>
    <a-layout class="container">
        <div class="slider">
            <a-layout-sider>
                <div class="text"><a>后台管理系统</a></div>
                <a-menu class="menu" style="width: 200px" mode="inline" theme="dark" v-model:openKeys="openKeys"
                    v-model:selectedKeys="selectedKeys" @click="handleClick">
                    <a-sub-menu v-for="i in list" :key="i.path" :index="i.path" @titleClick="titleClick">
                        <template #icon>
                            <component class="icons" :is="i.meta?.icon"></component>
                        </template>
                        <template #title class="title">
                            <router-link :to="'/home'">{{i.meta.title}}</router-link>
                        </template>
                        <a-menu-item v-for="it in i.children" :index="'/' + it.path" :key="it.path">
                            <template #icon>
                                <component class="icons" :is="it.meta?.icon"></component>
                            </template>
                            <router-link :to="i.path + '/' + it.path">
                                <span>{{ it.meta?.authName }}</span>
                            </router-link>
                        </a-menu-item>
                    </a-sub-menu>
                </a-menu>
            </a-layout-sider>
        </div>
        <a-layout>
            <a-layout-header height="80px" class="header" style="width:100%">
                <a-row>
                    <a-col :span="8"><a>管理服务1</a></a-col>
                    <a-col :span="8"><a>管理服务2</a></a-col>
                    <a-col :span="8"><a>管理服务3</a></a-col>
                </a-row>
            </a-layout-header>
            <a-layout-content style="width:100%">
                <router-view/>
            </a-layout-content>
        </a-layout>
    </a-layout>
</template>

router.ts(部分)

{
        path: '/home',
        component: () => import("../view/Home.vue"), // 按需引入
        // 子路由
        children:[
            { // 子路由1
                path: '', // 子路由不用斜杠
                name: 'home',
                meta:{
                    isShow:true, // 是否要在左侧区域渲染
                    title:"2022新生",
                    threeMenu: true,
                    icon:'MailOutlined',
                },
                // component: () => import("../view/Order.vue"), // 按需引入
                children:[
                    {
                        path: 'order',
                        name: 'order',
                        meta:{
                            authName:"新生文章区",
                            hidden: false, // 初始状态为隐藏
                            icon:'AppleOutlined',
                        },
                        component: () => import("../view/order.vue") // 按需引入
                    },
                    {
                        path: 'about_1',
                        name: 'about_1',
                        meta:{
                            authName:"新生瓷片区",
                            hidden: false,
                            icon:'InboxOutlined',
                        },
                        component: () => import("../view/About_1.vue") // 按需引入
                    },
                ]
            },
         }

整体搭建 layout布局

在ant design vue组件库中,layout布局可以直接复用。
在这里插入图片描述

<a-layout>
    <a-layout-sider>Sider</a-layout-sider>
    <a-layout>
      <a-layout-header>Header</a-layout-header>
      <a-layout-content>Content</a-layout-content>
      <!--这里的footer暂时用不到-->
      <!--<a-layout-footer>Footer</a-layout-footer>-->
    </a-layout>
  </a-layout>

左侧菜单栏 Menu🔥

ant design vue提供了全面的Menu菜单组件 可以直接复用
在这里插入图片描述
详细解释➕组件库api说明

<a-menu class="menu" style="width: 200px" mode="inline" theme="dark" v-model:openKeys="openKeys" v-model:selectedKeys="selectedKeys" @click="handleClick">
<!-- 内嵌式菜单 主题色黑色 点击事件-->
     <!-- 一级菜单-->
     <a-sub-menu v-for="i in list" :key="i.path" :index="i.path" @titleClick="titleClick">
     <!--下拉菜单栏  循环list中的元素i key值为i的path 标题点击事件-->
         <template #icon>
         <!-- icon引入-->
             <component class="icons" :is="i.meta?.icon"></component> 
             <!--icon的引入方式 按需引入 循环i中meta下的icon-->
         </template>
         <template #title class="title">
             <router-link :to="'/home'">{{i.meta.title}}</router-link>
             <!-- 用router-link实现点击跳转home页面-->
         </template>
         <!--二级菜单-->
         <a-menu-item v-for="it in i.children" :index="'/' + it.path" :key="it.path">
             <template #icon>
                 <component class="icons" :is="it.meta?.icon"></component>
                 <!--icon的引入方式 按需引入 循环i中meta下的icon-->
              </template>
              <!-- router-link跳转响应一级菜单路径下的二级菜单路径-->
              <router-link :to="i.path + '/' + it.path">
                  <span>{{ it.meta?.authName }}</span>
                  <!-- 循环显示二级菜单内容中的meta下的authName-->
              </router-link>
         </a-menu-item>
     </a-sub-menu>
 </a-menu>

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
不难发现,这样只是简单的实现了效果,但是很多细节仍需优化,比如有无子菜单的区分循环、菜单样式的渲染、路由的简化等。下期文章将对其做出优化,给出完善后的菜单渲染。

summary

组件库对于页面的构建十分重要,如果使用组件存在不足,可以移步官方文档。或者本专栏下的vue3+ant design vue+ts实战【ant-design-vue组件库引入】。以上就是v-for循环实现导航栏多级菜单的大概内容,下期文章将对其进行优化。

下期预告

vue3后台管理系统 菜单栏两种方式处理有无children的问题🔥🔥

vue3搜索的筛选功能🔥

(若大家对本专栏 可订阅 后期会持续更新新的内容~)

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Dorable_Wander

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

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

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

打赏作者

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

抵扣说明:

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

余额充值