el-menu如何根據(jù)多層樹形結(jié)構(gòu)遞歸遍歷展示菜單欄
前提條件
package.json如下所示,這是一個(gè)Vite + Vue3 + TS的項(xiàng)目
{
"name": "vue3-ts-vite-wen-zhang-ji-lu-xiang-mu",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"element-plus": "^2.4.2",
"vue": "^3.3.4"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"sass": "^1.69.5",
"typescript": "^5.0.2",
"vite": "^4.4.5",
"vue-tsc": "^1.8.5"
}
}下面為了方便,直接在App.vue組件中,代碼結(jié)構(gòu)如下所示,就一純凈項(xiàng)目,然后直接在App.vue中寫代碼

假設(shè)菜單等級(jí)只有兩個(gè)等級(jí)
如果菜單等級(jí)只有兩個(gè)等級(jí),那就沒有必要使用到遞歸了,直接遍歷,然后根據(jù)是否有children字段,判斷是一級(jí)菜單還是二級(jí)菜單就可以了。具體代碼如下所示:
<template>
<div style="width: 100%; height: 100%;">
<div class="common-layout">
<el-container>
<el-header>頭部</el-header>
<el-container>
<!-- 側(cè)邊欄區(qū)域 -->
<el-aside width="200px">
<el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose">
<template v-for="(item, index) in menuList" :key="index">
<el-sub-menu :index="item.path" v-if="item.children && item.children.length">
<template #title>
<el-icon>
<location />
</el-icon>
<span>{{ item.name }}</span>
</template>
<el-menu-item v-for="child in item.children" :key="child.id" :index="child.path">
{{ child.name }}
</el-menu-item>
</el-sub-menu>
<el-menu-item v-else :index="item.path">
<el-icon><setting /></el-icon>
<span>{{ item.name }}</span>
</el-menu-item>
</template>
</el-menu>
</el-aside>
<!-- 主題區(qū)域 -->
<el-main>
這是主題區(qū)域
</el-main>
</el-container>
</el-container>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Location, Setting } from '@element-plus/icons-vue'
interface MenuItem {
id: number;
name: string;
path: string;
icon?: string;
component?: string;
children?: MenuItem[];
}
const menuList = ref<MenuItem[]>(
[
{
id: 1,
name: '首頁',
path: '/',
icon: 'location',
component: 'home',
children: []
},
{
id: 2,
name: '用戶管理',
path: '/user',
icon: 'location',
component: 'user',
children: [
{
id: 3,
name: '用戶列表',
path: 'list',
icon: '',
component: 'userList',
children: []
},
{
id: 5,
name: '角色列表',
path: 'roleList',
icon: '',
component: 'userList',
children: []
}
]
},
{
id: 6,
name: '權(quán)限管理',
path: '/permission',
icon: 'setting',
component: 'permission',
children: [
{
id: 7,
name: '權(quán)限列表',
path: 'permissionList',
icon: '',
component: 'permissionList',
}
]
}
]
)
const handleOpen = (key: string, keyPath: string[]) => {
console.log(key, keyPath)
}
const handleClose = (key: string, keyPath: string[]) => {
console.log(key, keyPath)
}
</script>
<style scoped lang="scss">
.el-container {
width: 100%;
height: 100%;
}
</style>結(jié)果如下所示

但是如果菜單等級(jí)超過兩個(gè)等級(jí)或者多個(gè)等級(jí)的話
但是如果菜單等級(jí)超過兩個(gè)等級(jí)或者多個(gè)等級(jí)的話,這時(shí)就可以使用到組件遞歸的方式進(jìn)行了。目錄結(jié)構(gòu)如下所示:

App.vue
<template>
<div style="width: 100%; height: 100%;">
<div class="common-layout">
<el-container>
<el-header>頭部</el-header>
<el-container>
<!-- 側(cè)邊欄區(qū)域 -->
<el-aside width="200px">
<el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose">
<menu-items :items="menuList"></menu-items>
</el-menu>
</el-aside>
<!-- 主題區(qū)域 -->
<el-main>
這是主題區(qū)域
</el-main>
</el-container>
</el-container>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import MenuItems from './components/MenuItems.vue'
interface MenuItem {
id: number;
name: string;
path: string;
icon?: string;
component?: string;
children?: MenuItem[];
}
const menuList = ref<MenuItem[]>(
[
{
id: 1,
name: '首頁',
path: '/',
icon: 'location',
component: 'home',
children: []
},
{
id: 2,
name: '用戶管理',
path: '/user',
icon: 'location',
component: 'user',
children: [
{
id: 3,
name: '用戶列表',
path: 'list',
icon: '',
component: 'userList',
children: [
{
id: 4,
name: '用戶詳情',
path: 'userDetail',
icon: '',
component: 'userDetail',
children: []
}
]
},
{
id: 5,
name: '角色列表',
path: 'roleList',
icon: '',
component: 'userList',
children: []
}
]
},
{
id: 6,
name: '權(quán)限管理',
path: '/permission',
icon: 'setting',
component: 'permission',
children: [
{
id: 7,
name: '權(quán)限列表',
path: 'permissionList',
icon: '',
component: 'permissionList',
children: [
{
id: 8,
name: '權(quán)限詳情-1',
path: 'permissionDetail',
icon: '',
component: 'permissionDetail',
children: [
{
id: 9,
name: '權(quán)限詳情-2',
path: 'permissionDetail2',
icon: '',
component: 'permissionDetail2',
children: []
}
]
}
]
}
]
}
]
)
const handleOpen = (key: string, keyPath: string[]) => {
console.log(key, keyPath)
}
const handleClose = (key: string, keyPath: string[]) => {
console.log(key, keyPath)
}
</script>
<style scoped lang="scss">
.el-container {
width: 100%;
height: 100%;
}
</style>MenuItems.vue
<template>
<template v-for="item in items" :key="item.id">
<el-sub-menu v-if="item.children && item.children.length > 0" :index="item.path">
<template #title>
<span>{{ item.name }}</span>
</template>
<!-- 遞歸遍歷 -->
<menu-items :items="item.children" />
</el-sub-menu>
<el-menu-item v-else :index="item.path">
<span>{{ item.name }}</span>
</el-menu-item>
</template>
</template>
<script setup lang="ts">
interface MenuItem {
id: number;
name: string;
path: string;
icon?: string;
component?: string;
children?: MenuItem[];
}
defineProps<{
items: MenuItem[];
}>()
</script>結(jié)果如下所示

從圖中可以看出,無論是一層,二層,三層,四層結(jié)構(gòu)的樹形數(shù)據(jù),都可以在el-menu中展示。
關(guān)于遍歷時(shí)圖標(biāo)前的展示后續(xù)完善
關(guān)于點(diǎn)擊路由跳轉(zhuǎn)參考element plus的官網(wǎng)即可
到此這篇關(guān)于el-menu根據(jù)多層樹形結(jié)構(gòu)遞歸遍歷展示菜單欄的文章就介紹到這了,更多相關(guān)el-menu多層樹形結(jié)構(gòu)遞歸遍歷展示菜單欄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談vue中使用圖片懶加載vue-lazyload插件詳細(xì)指南
本篇文章主要介紹了淺談vue中使用圖片懶加載vue-lazyload插件詳細(xì)指南,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-10-10
基于Vue.js實(shí)現(xiàn)一個(gè)完整的登錄功能
在現(xiàn)代Web應(yīng)用中,用戶登錄功能是一個(gè)核心模塊,它不僅涉及到用戶身份驗(yàn)證,還需要處理表單驗(yàn)證、狀態(tài)管理、接口調(diào)用等多個(gè)環(huán)節(jié),本文將基于一個(gè)Vue.js項(xiàng)目中的登錄功能實(shí)現(xiàn),深入解析其背后的技術(shù)細(xì)節(jié),幫助開發(fā)者更好地理解和實(shí)現(xiàn)類似功能,需要的朋友可以參考下2025-02-02
創(chuàng)建Vue項(xiàng)目以及引入Iview的方法示例
這篇文章主要介紹了創(chuàng)建Vue項(xiàng)目以及引入Iview的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12
Vue.js使用帶有對(duì)象的 v-model 來創(chuàng)建自定義組件的詳細(xì)操作
本文介紹了如何在Vue.js中使用帶有對(duì)象的v-model來創(chuàng)建自定義組件,通過創(chuàng)建一個(gè)封裝了多個(gè)輸入字段的自定義組件,并使用計(jì)算屬性和深拷貝來處理對(duì)象狀態(tài),可以實(shí)現(xiàn)雙向數(shù)據(jù)綁定,感興趣的朋友跟隨小編一起看看吧2025-12-12
vue.js與后臺(tái)數(shù)據(jù)交互的實(shí)例講解
今天小編就為大家分享一篇vue.js與后臺(tái)數(shù)據(jù)交互的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-08-08
一文詳解Vue3中使用ref獲取元素節(jié)點(diǎn)
這篇文章主要介紹了一文詳解Vue3中使用ref獲取元素節(jié)點(diǎn),本文介紹在vue3的setup中使用composition?API獲取元素節(jié)點(diǎn)的幾種方法,需要的朋友可以參考一下2022-07-07
Vue中靈活拖拽的前端神器VueDraggablePlus的用法詳解
這篇文章主要介紹了一款功能強(qiáng)大、靈活易用的前端組件VueDraggablePlus,作為前端工程師,我們經(jīng)常會(huì)遇到需要實(shí)現(xiàn)拖拽功能的場(chǎng)景,而VueDraggablePlus正是為了解決這一痛點(diǎn)而誕生的,讓我們一起來看看它的特點(diǎn)和用法吧2024-03-03

