多级侧边菜单(递归)

需要编写两个文件 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>
相关推荐
孤酒独酌1 分钟前
一次断网重连引发的「模块加载缓存」攻坚战
前端
jinzeming9994 分钟前
Vue3 PDF 预览组件设计与实现分析
前端
NuLL5 分钟前
全场景智能克隆工具:超越 JSON.parse(JSON.stringify())
javascript
编程小Y5 分钟前
Vue 3 + Vite
前端·javascript·vue.js
GDAL15 分钟前
前端保存用户登录信息 深入全面讲解
前端·状态模式
大菜菜21 分钟前
Molecule Framework -EditorService API 详细文档
前端
Anita_Sun23 分钟前
😋 核心原理篇:线程池的 5 大核心组件
前端·node.js
灼华_26 分钟前
Web前端移动端开发常见问题及解决方案(完整版)
前端
_请输入用户名27 分钟前
Vue3 Patch 全过程
前端·vue.js
孟祥_成都28 分钟前
nest.js / hono.js 一起学!字节团队如何配置多环境攻略!
前端·node.js