首页 默认分类 正文
  • 本文约1350字,阅读需7分钟
  • 57
  • 0

vue3 element-plus el-sidebarMenu菜单组件递归

摘要

基于elementui-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. 渲染结果

vue3 element-plus el-menu组件递归

评论
友情链接