多级侧边菜单(递归)

需要编写两个文件 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>
相关推荐
松树戈44 分钟前
plus-ui&RuoYi-Vue-Plus 基于pgSql本地运行实践
前端·vue.js·spring boot·ui
new6669991 小时前
css画图形
前端·css
Yvonne爱编码2 小时前
CSS- 1.1 css选择器
前端·css·状态模式·html5·hbuilder
SHIPKING3932 小时前
【HTML】个人博客页面
javascript·css·html
山河故人1632 小时前
uniapp使用npm下载
前端·npm·uni-app
-曾牛2 小时前
基于微信小程序的在线聊天功能实现:WebSocket通信实战
前端·后端·websocket·网络协议·微信小程序·小程序·notepad++
一口一个橘子3 小时前
[ctfshow web入门] web72
前端·web安全·网络安全
Web极客码3 小时前
如何使用WordPress SEO检查器进行实时内容分析
前端·seo·wordpress
Stella25213 小时前
【Vue】CSS3实现关键帧动画
前端·vue.js·css3
junjun.chen06063 小时前
【在qiankun模式下el-dropdown点击,浏览器报Failed to execute ‘getComputedStyle‘ on ‘Window‘: parameter 1 is not o
前端·javascript·前端框架