Vue3使用递归组件封装El-Menu多级菜单

html 复制代码
<template>
    <aside class="menu">
        <el-scrollbar>
            <el-menu class="menu-main" router :default-active="route.path" unique-opened background-color="#18214C"
                text-color="#fff">
                <menuItem v-for="item in menuList" :item="item" :key="item.path" />
            </el-menu>
        </el-scrollbar>
    </aside>
</template> 
<script setup>
import menuItem from "./components/menuItem.vue"
import { useRoute } from "vue-router"
const route = useRoute()

const menuList = [
    {
        path: "/index",
        component: () => import("@/views/index.vue"),
        name: "index",
        meta: {
            title: "一级菜单"
        }
    },
    {
        path: "/level",
        name: "level",
        meta: {
            title: "多级菜单"
        },
        children: [
            {
                path: "/level/level-1",
                name: "level-1",
                meta: {
                    title: "多级菜单-1"
                },
                children: [
                    {
                        path: "/level/level-1/level-1-1",
                        component: () => import("@/views/level/level-1/level-1-1.vue"),
                        name: "level-1-1",
                        meta: {
                            title: "多级菜单-1"
                        }
                    }]
            },
            {
                path: "/level/level-2",
                component: () => import("@/views/level/level-2.vue"),
                name: "level-2",
                meta: {
                    title: "多级菜单-2"
                }
            }
        ]
    }
]


</script>
<style lang='scss' scoped>
.menu {
    height: 100vh;
    overflow: hidden;
    background-color: #18214C;

    &-main {
        border: none;
    }

    &-main:not(.el-menu--collapse) {
        width: 220px;
    }
}
</style>
html 复制代码
<template>
    <template v-if="item.meta && !item.meta.hidden">
        <el-sub-menu :index="item.path" :key="item.path" v-if="item?.children?.length > 0">
            <template #title>
                <el-icon>
                    <Aim />
                </el-icon>
                <span>{{ item.meta.title }}</span>
            </template>
            <menuItem v-for="child in item.children" :item="child" :key="child.path" />
        </el-sub-menu>
        <el-menu-item v-else :index="item.path">
            <el-icon>
                <Aim />
            </el-icon>
            <template #title>{{ item.meta.title }}</template>
        </el-menu-item>
    </template>
</template>
<script setup name="menuItem">
import { Aim } from '@element-plus/icons-vue'
const props = defineProps({
    item: {
        type: Object,
        default: () => { },
    },
})
</script>
<style lang='scss' scoped>
.el-menu-item.is-active {
    color: #fff;
    background: #2260FF;
}
</style>
相关推荐
韭菜炒大葱9 分钟前
前端经典面试题:从 URL 输入到页面展示,中间经历了什么?
前端·http·面试
swipe16 分钟前
纯函数、柯里化与函数组合:从原理到源码,构建更可维护的前端代码体系
前端·javascript·面试
远山枫谷17 分钟前
uniapp + Vue 自定义组件封装:自定义样式从入门到实战
前端·vue.js
Lee川21 分钟前
JavaScript 中的 `this` 与变量查找:一场关于“身份”与“作用域”的深度博弈
前端·javascript·面试
Kakarotto3 小时前
Canvas 直线点击事件处理优化
javascript·vue.js·canvas
顺遂3 小时前
基于Rokid CXR-M SDK的引导式作业辅导系统设计与实现
前端
代码搬运媛3 小时前
Generator 迭代器协议 & co 库底层原理+实战
前端
前端拿破轮3 小时前
从0到1搭建个人网站(三):用 Cloudflare R2 + PicGo 搭建高速图床
前端·后端·面试
功能啥都不会3 小时前
PM2 使用指南 - 踩坑记录
前端
HelloReader3 小时前
React 中 useState、useEffect、useRef 的区别与使用场景详解,终于有人讲明白了
前端