vue3 element-plus el-sidebarMenu菜单组件递归
demo http://blog.example.hizhiji.com/#/example?post=12
1. 声明组件
./sidebarMenu.vue
<template>
<template v-for="(item, index) in routes" :key="index">
<el-sub-menu
:route="item.path"
:index="item.path"
v-if="item.children && item.children.length">
<template #title>
<el-icon v-if="item.meta?.icon||item.icon">
<component :is="item.meta?.icon||item.icon"></component>
</el-icon>
<span>{{ item.meta?.name || item.name }}</span>
</template>
<qi-sidebarMenu :routes="item.children"></qi-sidebarMenu>
</el-sub-menu>
<el-menu-item
v-else
:route="item.path"
:index="item.path"
@mouseenter="menuItemEnter($event, item)"
@mouseleave="menuItemLeave">
<el-icon v-if="item.meta?.icon || item.icon">
<component :is="item.meta?.icon||item.icon"></component>
</el-icon>
<span>{{ item.meta?.name || item.name }}</span>
</el-menu-item>
</template>
<el-tooltip
ref="tooltipRef"
:visible="tooltipVisible"
placement="right"
:popper-options="{
modifiers: [
{
name: 'computeStyles',
options: {
adaptive: false,
enabled: false,
},
},
],
}"
:virtual-ref="menuItemRef"
virtual-triggering>
<template #content>
<span> {{ selectItem.meta?.name||selectItem.name}} </span>
</template>
</el-tooltip>
</template>
<script setup name="SidebarMenu">
const props = defineProps({
routes: {
type: Array,
default: []
},
isShowTooltip: {
typeof: Boolean,
default: false
}
})
import { reactive, ref } from 'vue'
const menuItemRef = ref()
const tooltipRef = ref()
let selectItem=reactive({})
const tooltipVisible = ref(false);
const menuItemEnter = (ev,item) => {
if(!props.isShowTooltip) return
selectItem=item
menuItemRef.value = ev.currentTarget;
tooltipVisible.value=true;
}
const menuItemLeave = (ev) => {
if (!props.isShowTooltip) return
tooltipVisible.value = false
}
</script>
<style lang="scss" scoped>
.el-menu-item {
&.is-active {
background: #fff;
}
}
</style>
2. 组件调用
./menu.vue
<template>
<el-menu
class="menu"
:class="{ 'menu-colse': isMenuCollapse }"
:default-active="route.path"
:collapse="isMenuCollapse"
:unique-opened="true"
menu-trigger="click"
:router="true"
background-color="var(--el-color-primary)"
text-color="#ffffffa6"
active-text-color="var(--el-color-primary)">
<qi-sidebarMenu :routes="navRouter" :isShowTooltip="isMenuCollapse"></qi-sidebarMenu>
</el-menu>
</template>
<script setup>
import { ref, reactive } from "vue";
const isMenuCollapse = ref(false);
const navRouter = reactive([
{
path: '/slect1/',
name: '选项1',
icon: 'UserFilled',
children:[
{
path: '/slect1-1/',
name: '选项1-1',
icon: 'UserFilled',
children: [
{
path: '/slect1-1-1/',
name: '选项1-1-1',
icon: 'UserFilled',
}
],
},
{
path: '/slect1-2/',
name: '选项1-2',
icon: 'UserFilled',
}
]
},
{
path: '/slect2/',
name: '选项2',
icon: 'UserFilled',
},
{
path: '/slect3/',
name: '选项3',
icon: 'UserFilled',
}
])
</script>
<style lang="scss">
.menu:not(.el-menu--collapse) {
width: 200px;
height: 100%;
border: none;
}
.menu {
position: relative;
flex-shrink: 0;
.el-menu-item {
width: 80%;
&.is-active {
background: #0c88e8;
color: #fff;
font-weight: bold;
}
&:hover {
background-color: none !important;
color: #fff;
}
}
}
</style>
3. 渲染结果
