Vue如何跨組件傳遞Slot的實(shí)現(xiàn)
在開(kāi)發(fā)過(guò)程中遇到這樣一個(gè)問(wèn)題,如何跨組件傳遞插槽。因?yàn)樵陂_(kāi)發(fā)類(lèi)似樹(shù)組件的過(guò)程中,插槽需要通過(guò)外部傳遞到樹(shù)的根節(jié)點(diǎn),然后通過(guò)根節(jié)點(diǎn)依次傳遞到各個(gè)葉子節(jié)點(diǎn)。那么如何把根節(jié)點(diǎn)的Slot如傳遞給子組件呢?
我們?cè)陂_(kāi)發(fā)過(guò)程中,希望可以這樣實(shí)現(xiàn)重新定義葉子節(jié)點(diǎn)的結(jié)構(gòu):
<data-tree>
<template v-slot:node="data">
<div>{{data.title}} - {{data.text}}</div>
</template>
</data-tree>
那么如何在組件內(nèi)傳遞Slot就是一個(gè)問(wèn)題。
嵌套傳遞
通過(guò)固定級(jí)別的組件結(jié)構(gòu)里可以通過(guò)直接書(shū)寫(xiě)<v-slot ...>來(lái)傳遞對(duì)應(yīng)的Slot元素,來(lái)實(shí)現(xiàn)一層一層的傳遞。
<data-tree>
<data-tree-item>
<template :node="data">
<slot :data="data"> xxx </slot>
</template>
</data-tree-item>
</data-tree>
通過(guò)在外層創(chuàng)建slot可以逐層將slot進(jìn)行傳遞,但是如果過(guò)多的嵌套層次,這樣就顯得很麻煩。
Render
還有一種方案是通過(guò)Render函數(shù)來(lái)進(jìn)行顯示,可以通過(guò)$slots來(lái)訪問(wèn)當(dāng)前組件的slot元素,然后通過(guò)Render函數(shù)創(chuàng)建新組件時(shí),將slot傳遞給下一層。
h('data-tree-item',{
scopedSlots: {
node: props => this.$slots.node(props)
},
})
這樣通過(guò)Render子元素就可以接受到對(duì)應(yīng)的Slot,也實(shí)現(xiàn)了傳遞。
動(dòng)態(tài)組件
還有一種方式是通過(guò)動(dòng)態(tài)組件,也是認(rèn)為比較推薦的實(shí)現(xiàn)方式,不是通過(guò)傳遞Slot,而是通過(guò)子節(jié)點(diǎn)主動(dòng)去獲取根節(jié)點(diǎn)的Slot對(duì)象,然后直接在UI中渲染出來(lái)。
為此我們需要?jiǎng)?chuàng)建一個(gè)組件來(lái)渲染對(duì)應(yīng)的Slot對(duì)象。
首先需要獲取根節(jié)點(diǎn):
const rootComponentName = 'data-tree'
/**
* 獲取父組件
*/
const getRootComponent = (
component: ComponentInternalInstance | null
): ComponentInternalInstance | undefined => {
if (component && component.type.name === rootComponentName) {
return component
}
if (component && component.parent) {
const parent = component.parent
return getRootComponent(parent)
}
}
通過(guò)遞歸我們可以獲取到對(duì)應(yīng)的父節(jié)點(diǎn),這樣我們就可以把Slot作為Data暴露出來(lái)
setup(props) {
// 獲取根節(jié)點(diǎn)
const dataTree = getRootComponent(getCurrentInstance())
const parentSlots = dataTree?.slots
const nodeTemplate = parentSlots?.node as any
return {
nodeTemplate
}
}
這時(shí)候我們需要一個(gè)組件來(lái)渲染暴露出來(lái)的Slot:
components: {
TemplateContainer: {
functional: true,
props: {
template: {
type: Function
},
data: {
type: Object
}
},
render: (props, ctx) => h('div', [props.template(props.data)])
}
}
好了現(xiàn)在該準(zhǔn)備的都準(zhǔn)備好了,可以去實(shí)現(xiàn)UI的顯示了:
<template-container
v-if="nodeTemplate"
:template="nodeTemplate"
:data="node">
</template-container>
<template v-else>
{{ node.label }}
</template>
這樣我們就實(shí)現(xiàn)了類(lèi)似下面定義Slot的傳遞,也解決了我們跨組件傳遞Slot的問(wèn)題。
<slot :data="node" name="node">
{{ node.label }}
</slot>
本文使用的是Vue 3的事例,Vue 2也是相同的概念,在Vue 3中除了使用getRootComponent來(lái)查詢(xún)跟節(jié)點(diǎn),也可以使用Provide/Inject來(lái)將Slot主動(dòng)傳遞給子節(jié)點(diǎn)。
到此這篇關(guān)于Vue如何跨組件傳遞Slot的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Vue 跨組件傳遞Slot內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue使用動(dòng)態(tài)組件手寫(xiě)Router View實(shí)現(xiàn)示例
這篇文章主要為大家介紹了vue使用動(dòng)態(tài)組件手寫(xiě)RouterView實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
Vue項(xiàng)目打包部署全過(guò)程(history模式)
vue項(xiàng)目中我們比較常用的模式為hash和history模式,下面這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目打包部署的全過(guò)程,講解的是vue-router中history模式的部署,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05
關(guān)于Vue項(xiàng)目跨平臺(tái)運(yùn)行問(wèn)題的解決方法
這篇文章主要介紹了關(guān)于Vue項(xiàng)目跨平臺(tái)運(yùn)行問(wèn)題的解決方法,特別記錄一下踩的坑,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09
vue實(shí)現(xiàn)高德地圖添加多個(gè)點(diǎn)標(biāo)記
地圖多點(diǎn)標(biāo)注其實(shí)是個(gè)非常簡(jiǎn)單的問(wèn)題,這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)高德地圖添加多個(gè)點(diǎn)標(biāo)記的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
詳解如何使用 vue-cli 開(kāi)發(fā)多頁(yè)應(yīng)用
本篇文章主要介紹了詳解如何使用 vue-cli 開(kāi)發(fā)多頁(yè)應(yīng)用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
vue3中使用vuex和vue-router的詳細(xì)步驟
這篇文章主要介紹了vue3中使用vuex和vue-router的步驟,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12
Vue.js實(shí)現(xiàn)輸入框綁定的實(shí)例代碼
這篇文章主要介紹了Vue.js實(shí)現(xiàn)輸入框綁定的實(shí)例代碼,需要的朋友可以參考下2017-08-08
一步步從Vue3.x源碼上理解ref和reactive的區(qū)別
vue3的數(shù)據(jù)雙向綁定,大家都明白是proxy數(shù)據(jù)代理,但是在定義響應(yīng)式數(shù)據(jù)的時(shí)候,有ref和reactive兩種方式,如果判斷該使用什么方式,是大家一直不很清楚地問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于從Vue3.x源碼上理解ref和reactive的區(qū)別的相關(guān)資料,需要的朋友可以參考下2023-02-02

