本文簡介
點贊 + 關(guān)注 + 收藏 = 學(xué)會了
在日常 Vue 項目中簿透,大概率會用組件庫輔助開發(fā)铅碍,所以 遞歸組件 的出鏡率可能不會非常高热鞍。但這并不代表 遞歸組件 不重要闷尿。
本文用10分鐘左右的時間讓你掌握 遞歸組件 的用法塑径。
在此之前,你必須掌握:html
+ css
+ js
+ Vue3
基礎(chǔ)用法填具,至少需要知道 Vue 組件
是什么统舀。
用法講解
在講解 遞歸組件 之前,我們需要先了解幾個概念劳景。
什么是遞歸誉简?
遞歸在百度百科里的定義是:
程序調(diào)用自身的編程技巧稱為遞歸( recursion)
你可以將 遞歸 粗略的理解為 循環(huán) ,只不過 遞歸 是調(diào)用自身盟广。
在實際使用中闷串,需要給遞歸設(shè)置一個邊界條件,用該邊界條件來判斷是否繼續(xù)遞歸下去筋量。
如果不設(shè)置判斷條件烹吵,將會導(dǎo)致 無限遞歸 碉熄,也就是 死循環(huán)!
什么是遞歸組件肋拔?
看到這里锈津,我相信大家是知道 Vue組件
是什么。
我先把 《Vue3 遞歸組件 文檔》 放在這凉蜂。
其實 遞歸組件 就是把 “遞歸” 和 “組件” 結(jié)合起來琼梆。
組件在邊界條件內(nèi)不斷調(diào)用自己,直到超出邊界條件為止窿吩。
遞歸組件在哪會用到茎杂?
在我工作中會出現(xiàn)遞歸組件的情況有:
- “樹”組件:用來展示文件層級的。
- 左側(cè)導(dǎo)航欄:根據(jù)路由層級生成的導(dǎo)航菜單纫雁。
- 多級表格(嵌套的表格)蛉顽。
上手實操
經(jīng)過前面的講解,相信大家對 遞歸組件 已經(jīng)有一定的概念了先较。
接下來通過一個簡單的例子來講解携冤。
上圖就是本次要實現(xiàn)的例子。
我沒有寫樣式闲勺,大家將就一下曾棕,用想象力把這想象成網(wǎng)站的左側(cè)導(dǎo)航欄吧。
這種導(dǎo)航欄菜循,有在前端寫死的翘地;也有寫業(yè)務(wù)是需要后端配置,前端把導(dǎo)航欄數(shù)據(jù)請求回來再生成路由的癌幕。
所以可以理解為前端一開始不知道這個導(dǎo)航有多少層級衙耕。
這時就可以通過 遞歸組件 的方式來實現(xiàn)。
步驟如下:
- 創(chuàng)建導(dǎo)航組件
- 全局注冊導(dǎo)航組件
- 獲取數(shù)據(jù)(本例以學(xué)習(xí)為目的勺远,所以在前端寫死數(shù)據(jù))
- 在導(dǎo)航組件中設(shè)置遞歸邊界橙喘,并渲染數(shù)據(jù)
1、創(chuàng)建組件
我給導(dǎo)航組件命名為 RootNav.vue
胶逢。并將它放在 components
目錄下厅瞎。
RootNav.vue
<template>
<div>
Rootnav
</div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>
此時項目目錄如下:
省略部分目錄和文件
- src
|- main.js
|- App.vue
|- components
|- RootNav.vue
2、全局注冊組件
我在全局注冊 RootNav.vue
組件初坠,這樣就方便 RootNav.vue
自己調(diào)用自己了和簸。
main.js
import { createApp } from 'vue'
import App from './App.vue'
import RootNav from './components/RootNav.vue' // 引入 RootNav 組件
const app = createApp(App)
app.component('RootNav', RootNav) // 將 RootNav 注冊成全局組件
app.mount('#app')
在 App.vue
中使用
App.vue
<template>
<div>
<RootNav />
</div>
</template>
此時瀏覽器的界面如上圖所示。
3碟刺、獲取導(dǎo)航數(shù)據(jù)
在真實項目中锁保,左側(cè)導(dǎo)航可能是從后端獲取的。
但本文的目的是學(xué)習(xí)遞歸組件,所以就直接在前端模擬了一份 “請求回來的數(shù)據(jù)”爽柒。
我把 “請求數(shù)據(jù)” 的操作放在 App.vue
吴菠。然后再通過 props
的方式傳入到 RootNav.vue
組件內(nèi)。
講到 props
我就順便提一下:《Vue3 過10種組件通訊方式》
App.vue
<template>
<div>
<RootNav :list="navList" />
</div>
</template>
<script setup>
const navList = [
{
name: '一級導(dǎo)航 1'
},
{
name: '一級導(dǎo)航 2',
children: [
{ name: '二級導(dǎo)航 2-1' },
{
name: '二級導(dǎo)航 2-2',
children: [
{ name: '三級導(dǎo)航 2-2-1' },
{ name: '三級導(dǎo)航 2-2-2' },
]
},
{ name: '二級導(dǎo)航 2-2' }
]
},
{
name: '一級導(dǎo)航 3'
}
]
</script>
RootNav.vue
<template>
<div>
RootNav
</div>
</template>
<script setup>
const props = defineProps({
list: {
type: Array,
default: () => []
}
})
</script>
此時在 RootNav.vue
里就接收到 “請求回來的導(dǎo)航數(shù)據(jù)” 了霉赡。
4、設(shè)置遞歸邊界幔托,并渲染數(shù)據(jù)
我們看到導(dǎo)航數(shù)據(jù)有 children
字段穴亏,這個字段是 “子菜單” 的意思。
我們可以通過是否存在 children
字段來判斷是否需要繼續(xù)遞歸重挑。也就是說嗓化,children
就是遞歸的邊界條件。
RootNav.vue
<template>
<ul>
<template v-for="item in list">
<li>{{ item.name }}</li>
<RootNav v-if="'children' in item" :list="item.children" />
</template>
</ul>
</template>
<script setup>
const props = defineProps({
list: {
type: Array,
default: () => []
}
})
</script>
這部分的重點在 HTML
代碼里谬哀。
到這就完成了最開始的目標(biāo)了刺覆。
完整代碼
main.js
import { createApp } from 'vue'
import App from './App.vue'
import RootNav from './components/RootNav.vue'
const app = createApp(App)
app.component('RootNav', RootNav)
app.mount('#app')
App.vue
<template>
<div>
<RootNav :list="navList" />
</div>
</template>
<script setup>
const navList = [
{
name: '一級導(dǎo)航 1'
},
{
name: '一級導(dǎo)航 2',
children: [
{ name: '二級導(dǎo)航 2-1' },
{
name: '二級導(dǎo)航 2-2',
children: [
{ name: '三級導(dǎo)航 2-2-1' },
{ name: '三級導(dǎo)航 2-2-2' },
]
},
{ name: '二級導(dǎo)航 2-2' }
]
},
{
name: '一級導(dǎo)航 3'
}
]
</script>
components/RootNav.vue
<template>
<ul>
<template v-for="item in list">
<li>{{ item.name }}</li>
<RootNav v-if="'children' in item" :list="item.children" />
</template>
</ul>
</template>
<script setup>
const props = defineProps({
list: {
type: Array,
default: () => []
}
})
</script>
推薦閱讀
??《Vite 搭建 Vue2 項目(Vue2 + vue-router + vuex)》
如果本文對你有幫助,也希望你可以 點贊 關(guān)注 收藏 ~ 這對我很有用 ~