Vue遞歸實(shí)現(xiàn)樹(shù)形菜單方法實(shí)例
什么是樹(shù)形菜單還是要簡(jiǎn)單的啰嗦一下,比如:

上圖是截圖自elementui的實(shí)例,實(shí)現(xiàn)方式是用文檔結(jié)構(gòu)(類(lèi)似像原生Dom文檔結(jié)構(gòu)的寫(xiě)法)的方式,好處就是很靈活,可以方便的自定義,作為一個(gè)通用視圖組件庫(kù)這是正確的做法。
在實(shí)際的企業(yè)應(yīng)用中,菜單要比這復(fù)雜很多,層次也要多很多,如果我們采取手動(dòng)編寫(xiě)文檔結(jié)構(gòu)的方式,會(huì)導(dǎo)致代碼亢長(zhǎng),閱讀和維護(hù)都很低效。毫無(wú)疑問(wèn)所有Vuer都會(huì)想到用一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)驅(qū)動(dòng)文檔結(jié)構(gòu)。vue-router的數(shù)據(jù)結(jié)構(gòu)恰恰就是完美的嵌套層次結(jié)構(gòu)(樹(shù)結(jié)構(gòu)),同時(shí)vue文檔中也提到了遞歸組件,基于這兩點(diǎn),我們來(lái)擼碼,不過(guò)這次有所不同,我們選擇使用render函數(shù)來(lái)實(shí)現(xiàn),而不是在模板中遞歸。
數(shù)據(jù)結(jié)構(gòu):vue-router的數(shù)據(jù)結(jié)構(gòu)
const routes = [
{
name: 'home',
path: '/home',
meta: { text: '首頁(yè)' }
},
{
name: 'inner',
path: '/inner',
meta: { text: '內(nèi)部平臺(tái)' },
children: [
{
name: 'oa',
path: 'oa',
meta: { text: 'OA' }
},
{
name: 'jira',
path: 'jira',
meta: { text: 'Jira' }
},
{
name: 'wiki',
path: 'wiki',
meta: { text: 'Wiki' }
},
{
name: 'caiwu',
path: 'caiwu',
meta: { text: '財(cái)務(wù)' },
children: [
{
name: 'chailv',
path: 'chailv',
meta: { text: '差旅' }
},
{
name: 'richang',
path: 'richang',
meta: { text: '日常' },
children: [
{
name: 'taxi',
path: 'taxi',
meta: { text: '交通' }
},
{
name: 'tel',
path: 'tel',
meta: { text: '通信' }
}
]
}
]
}
]
},
{
name: 'sec',
path: '/sec',
meta: { text: '審核' },
children: [
{
name: 'acl',
path: '/acl',
meta: { text: 'ACL' }
}
]
}
]
組件實(shí)現(xiàn):
先看看render函數(shù),其中包含一個(gè)遞歸函數(shù)elements:
render (r) {
return r(
'el-menu',
{
props: {
backgroundColor: "#545c64",
textColor: "#fff",
activeTextColor: "#ffd04b"
},
on: {
select: this.onSelect
}
},
this.elements(this.routes, r)
)
}
elements函數(shù):
elements (routes, r) {
return routes
.map(route => {
if (!route.paths) route.paths = []
if (route.children && route.children.length) {
return r(
'el-submenu',
{
props: {
index: route.name
}
},
[
r(
'span',
{
slot: 'title'
},
[
route.meta.text
]
),
this.elements(route.children, r)
]
)
} else if (route.path) {
return r(
'el-menu-item',
{
props: {
index: route.name
}
},
[
route.meta.text
]
)
} else {
return null
}
})
.filter(item => item)
}
最終效果:

完整代碼示例請(qǐng)戳:https://codepen.io/360vislab/pen/GQqBve
總結(jié):
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
優(yōu)雅的將ElementUI表格變身成樹(shù)形表格的方法步驟
這篇文章主要介紹了優(yōu)雅的將ElementUI表格變身成樹(shù)形表格的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
在vue3中使用el-tree-select實(shí)現(xiàn)樹(shù)形下拉選擇器效果
el-tree-select是一個(gè)含有下拉菜單的樹(shù)形選擇器,結(jié)合了?el-tree?和?el-select?兩個(gè)組件的功能,這篇文章主要介紹了在vue3中使用el-tree-select做一個(gè)樹(shù)形下拉選擇器,需要的朋友可以參考下2024-03-03
Vue Element UI 中 el-table 樹(shù)形數(shù)據(jù) 
這篇文章主要介紹了Vue Element UI 中 el-table 樹(shù)形數(shù)據(jù) tree-props 多層級(jí)使用避坑指南,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
vue-admin-template配置快捷導(dǎo)航的代碼(標(biāo)簽導(dǎo)航欄)
這篇文章主要介紹了vue-admin-template配置快捷導(dǎo)航的方法(標(biāo)簽導(dǎo)航欄),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09

