有一個需求,需要我們渲染一個未知層級關係的cascader級聯選擇器。這樣在template模版當中是無法寫死v-for嵌套的,因爲數據是活的,可能三個嵌套子集,也有可能有四個。下面是element-ui當中的例子:
那麼我們如何解決這個需求呢?
用遞歸組件。
html:
<cascader :source="source">聯級選擇框</cascader>
數據結構:
data: {
source: [
{
name: '浙江',
children: [
{
name: '杭州',
children: [
{name: 'shang'},
{name: 'xia'},
{name: 'jianggan'}
]
},
{
name: '嘉興',
children: [
{name: 'shang'},
{name: 'xia'},
{name: 'jianggan'}
]
}
]
},
{
name: '湖南',
children: [
{
name: '長沙',
children: [
{name: 'shang'},
{name: 'xia'},
{name: 'jianggan'}
]
},
{
name: '湘潭',
children: [
{name: 'shang'},
{name: 'xia'},
{name: 'jianggan'}
]
}
]
},
]
},
cascader組件內部:也就是將外部得到的全部數據統一傳到cascader組件中處理。
<template>
<div class="cascader-content">
<div class="trigger">
<slot></slot>
</div>
<div class="popover">
<!-- 遞歸組件-->
<cascader-item v-for="(item, index) in source" :key="index" :sourceItem="item"></cascader-item>
</div>
</div>
</template>
<script>
import cascaderItem from './cascader-item'
export default {
name: 'cascader',
components: {cascaderItem},
props: {
source: {
type: Array
}
},
}
</script>
cascader-item組件內部:這個組件進行遞歸調用。
<template>
<div class="cascader-item-content">
{{sourceItem.name}}
<cascader-item
v-if="sourceItem.children"
v-for="item in sourceItem.children"
:sourceItem="item">
</cascader-item>
</div>
</template>
<script>
export default {
name: 'cascaderItem',
props: {
sourceItem: {
type: Object
}
},
}
</script>
在vue只需要聲明組件的name,即可在template模版中使用當前組件name作爲組件標籤進行自身調用,這樣就能滿足無需提前知道有幾層嵌套,通過遞歸v-for都能遍歷出來,這就是遞歸組件調用大致雛形,樣式功能可以根據需求繼續完善。遞歸組件特別適合用於cascader級聯選擇器、tree樹等功能。
最後在頁面中渲染出如下結果: