效果图

所有代码
<template>
<div class="y_aside">
<el-scrollbar>
<client-only>
<el-menu :default-active="data.defaultActive" :collapse="data.isCollapse" class="el-menu-vertical-demo">
<YMenu v-for="item in data.menus" :menu="item" :key="item.path" />
</el-menu>
</client-only>
</el-scrollbar>
</div>
</template>
<script setup lang="jsx">
import {
Menu as IconMenu,
} from '@element-plus/icons-vue'
const router = useRouter();
const route = useRoute();
const data = reactive({
isCollapse: false,
defaultActive: "/main/supplier",
menus: [
{
name: "供应商",
path: "/main/supplier",
},
{
name: "客户中心",
path: "/main/customer",
children: [
{
name: "问答库",
path: "/main/customer/question",
},
{
name: "问答库1",
path: "/main/customer/question1",
children: [
{
name: "hhh",
path: "/main/customer/question1/hhh"
}
]
}
]
},
{
name: "工作计划",
path: "/main/workplan"
},
]
});
const YMenu = (props) => {
const { menu } = props
if (menu.children && menu.children instanceof Array && menu.children.length) {
const subMenuSlots = {
title: () => (
<>
<ElIcon><IconMenu /></ElIcon>
<span>{menu.name}</span>
</>
)
}
return (
<ElSubMenu v-slots={subMenuSlots} index={menu.path}>
{menu.children.map(item => <YMenu menu={item} />)}
</ElSubMenu>
)
}
const menuItemSlots = {
title: () => <span>{menu.name}</span>
}
return (
<ElMenuItem v-slots={menuItemSlots} onClick={() => toUrl(menu.path)} index={menu.path}>
<ElIcon><IconMenu /></ElIcon>
</ElMenuItem>
)
}
const toUrl = (path) => {
router.push(path);
};
watch(
() => route.path,
(newValue) => {
data.defaultActive = newValue;
},
{
immediate: true
}
)
</script>
<style scoped lang="scss">
.y_aside {
height: 100%;
display: flex;
flex-direction: column;
position: relative;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 400px;
}
:deep(.el-scrollbar) {
flex: 1;
background-color: transparent;
}
:deep(.el-menu) {
flex: 1;
border-right: 0;
background-color: transparent;
}
:deep(.el-menu-item.is-active) {
background: #e7f8f5;
color: #15BC9C;
}
</style>