需要编写两个文件 aside-menu.vue 和 menu-item.vue
- 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>
- 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>
- 使用我们编写的 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>