需要编写两个文件 aside-menu.vue 和 menu-item.vue
- menu-item.vue
<script setup>
defineOptions({name: 'MenuItem'})
defineProps({menuList: Array})
</script>
<template>
<template v-for="menu of menuList">
<!-- 如果当前有子菜单,则显示 el-sub-menu ,在el-sub-menu 里调用 递归组件 -->
<el-sub-menu
v-if="menu.children && menu.children.length > 0"
:index="menu.path"
>
<template #title>
<el-icon>
<component :is="menu.icon"></component>
</el-icon>
<span>{{ menu.name }}</span>
</template>
<!-- 调用自身 此处是重点-->
<MenuItem :menuList="menu.children"></MenuItem>
</el-sub-menu>
<!-- 如果没有子菜单,则显示当前内容 -->
<el-menu-item v-else :index="menu.path">
<el-icon>
<component :is="menu.icon"></component>
</el-icon>
<template #title>
<span>{{ menu.name }}</span>
</template>
</el-menu-item>
</template>
</template>
<style lang="scss" scoped>
</style>
- aside-menu.vue (menuList在该组件中请求后端接口获取)
<script setup>
import MenuItem from "./menu-item.vue";
defineProps({
isCollapse: {
type: Boolean,
default: true
}
})
// 菜单列表
let menuList = [
{
path: '/',
name: '首页',
icon: 'HomeFilled'
},
{
path: '/about',
name: '关于',
icon: 'document'
},
{
path: '/test',
name: '测试',
icon: 'Star',
children: [
{
path: '/test/test1',
name: '测试1',
icon: 'Star',
},
{
path: '/test/test2',
name: '测试2',
icon: 'Star',
children: [
{
path: '/test/test2/test1',
name: '测试1',
icon: 'Star',
},
]
},
{
path: '/test/test3',
name: '测试3',
icon: 'Star',
hidden: true,
}
],
},
{
path: '/test2',
name: '测试2',
icon: 'Star',
children: [
{
path: '/test2/test1',
name: '测试1',
icon: 'Star',
hidden: true,
},
]
},
]
//通过递归 将 menuList 属性hidden为true的菜单及其子菜单过滤掉
function filterHiddenMenu(menuList) {
return menuList.filter(menu => {
if (menu.children) {
menu.children = filterHiddenMenu(menu.children)
}
return !menu.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组件
<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>