多级侧边菜单(递归)

需要编写两个文件 aside-menu.vue 和 menu-item.vue

  1. menu-item.vue
html 复制代码
<script setup>
defineOptions({name: 'MenuItem'})
defineProps({menuList: Array})
</script>

<template>
  <template v-for="menu of menuList">
    <!-- 如果当前有子菜单,且子菜单只有一个时 -->
    <el-menu-item v-if="menu.children && menu.children.length === 1" :index="menu.path">
      <el-icon>
        <component :is="menu?.meta?.icon"></component>
      </el-icon>
      <template #title>
        <span>{{ menu.children[0]?.meta?.title }}</span>
      </template>
    </el-menu-item>
    <!-- 如果当前有子菜单,且子菜单大于一个时 -->
    <el-sub-menu
        v-if="menu.children && menu.children.length > 1"
        :index="menu.path"
    >
      <template #title>
        <el-icon>
          <component :is="menu?.meta?.icon"></component>
        </el-icon>
        <span>{{ menu?.meta?.title }}</span>
      </template>
      <!-- 调用自身  此处是重点-->
      <MenuItem :menuList="menu.children"></MenuItem>
    </el-sub-menu>
    <!-- 如果没有子菜单,则显示当前内容 -->
    <el-menu-item v-if="!menu.children || menu.children.length===0" :index="menu.path">
      <el-icon>
        <component :is="menu?.meta?.icon"></component>
      </el-icon>
      <template #title>
        <span>{{ menu?.meta?.title }}</span>
      </template>
    </el-menu-item>
  </template>
</template>

<style lang="scss" scoped>

</style>
  1. aside-menu.vue (menuList在该组件中请求后端接口获取)
html 复制代码
<script setup>
import MenuItem from "./menu-item.vue";

defineProps({
  isCollapse: {
    type: Boolean,
    default: true
  }
})
// 菜单列表
let menuList =[
    {
        path: '/',
        name: 'Layout',
        redirect: '/home',
        component: '/views/layout/index',
        meta: {
            title: 'Layout',
            icon: 'HomeFilled',
            hidden: false
        },
        children: [
            {
                path: '/home',
                name: 'Home',
                component: '/views/home/index',
                meta: {
                    title: '首页',
                    icon: 'HomeFilled',
                    hidden: false
                }
            },
        ]
    },
    {
        path: '/sys',
        name: 'Sys',
        component: '/views/layout/index',
        meta: {
            title: '系统管理',
            icon: 'document',
            hidden: false
        },
        children: [
            {
                path: '/sys/user',
                name: 'User',
                component: '/views/sys/user/index',
                meta: {
                    title: '用户管理',
                    icon: 'document',
                    hidden: false
                }
            },
            {
                path: '/sys/role',
                name: 'Role',
                component: '/views/sys/role/index',
                meta: {
                    title: '角色管理',
                    icon: 'document',
                    hidden: false
                }
            },
        ]
    }
]

//通过递归 将 menuList 属性hidden为true的菜单及其子菜单过滤掉
function filterHiddenMenu(menuList) {
  return menuList.filter(menu => {
    if (menu.children) {
      menu.children = filterHiddenMenu(menu.children)
    }
    return !menu?.mata?.hidden
  })
}

menuList = filterHiddenMenu(menuList)
</script>

<template>
  <div>
    <el-menu :collapse="isCollapse" :collapse-transition="false">
      <MenuItem :menu-list="menuList"></MenuItem>
    </el-menu>
  </div>
</template>

<style lang="scss" scoped>
.el-menu {
  height: 100%;
  width: 100%;
}
</style>
  1. 使用我们编写的 aside-menu组件
html 复制代码
<script setup>
import {ref} from "vue";
import AsideMenu from "./aside-menu/index.vue";

// 是否折叠菜单,默认折叠
const isCollapse = ref(true)

</script>

<template>
    <AsideMenu :isCollapse="isCollapse"></AsideMenu>
</template>

<style scoped lang="scss">
</style>
相关推荐
阿成学长_Cain16 分钟前
Linux talk 命令详解:经典终端实时聊天工具,无需图形界面即可对话
linux·运维·前端
lichenyang45328 分钟前
从零开始写 HarmonyOS Web 容器:先让 ArkWeb 加载本地 H5
前端
kyriewen36 分钟前
一个看不见的撇号,让Claude Code追踪了中国开发者三个月
前端·ai编程·claude
莫生灬灬40 分钟前
DY联系人聊天Web面板支持获取联系人/聊天记录/发送消息
前端·chrome·websocket·c#
郑州光合科技余经理1 小时前
海外外卖平台源码改造实战——多语言核心代码实现
java·开发语言·前端·后端·mysql·架构·php
一tiao咸鱼1 小时前
前端转 agent # 02 - FastAPI 框架入门与原理
前端·python
wanghowie1 小时前
LangGraph4j 落地(二)— ReAct 多步工具与 trace 扩展
前端·react.js·前端框架
大家的林语冰2 小时前
Rust 再次打败 Go,Astro 7 首发,什么叫“万物皆可锈化“!
前端·javascript·性能优化
lichenyang4532 小时前
H5 如何调用 ArkTS:JavaScriptProxy、requestId 和 Promise 回调
前端
lichenyang4532 小时前
我在 HarmonyOS 上写了一个轻量级小程序运行时:从 Web 容器到 JSBridge
前端