
vue里提供了一種將父組件的內(nèi)容和子組件的模板整合的方法:內(nèi)容分發(fā),通過(guò)slot插槽來(lái)實(shí)現(xiàn)。
在組件標(biāo)簽內(nèi)部寫入的內(nèi)容默認(rèn)的會(huì)被替換掉,如果想要在組件的模板里使用這些內(nèi)容,就在對(duì)應(yīng)的位置寫上slot標(biāo)簽,這個(gè)slot標(biāo)簽就代表著這些內(nèi)容。
匿名槽口
在父組件中使用子組件的時(shí)候,在子組件標(biāo)簽內(nèi)部寫的內(nèi)容,在子組件的模板中可以通過(guò)<slot></slot>來(lái)使用
<div id = "app">
<aaa>
<h3>slot槽口插入的內(nèi)容</h3>
</aaa>
</div>
<template id="aaa">
<div class = "aaa">
<slot></slot>
<p>我是aaa組件</p>
</div>
</template>

具名槽口
父組件在子組件標(biāo)簽內(nèi)寫的多個(gè)內(nèi)容我們可以給其設(shè)置slot屬性來(lái)命名,在子組件的模板通過(guò)使用帶有name屬性的slot標(biāo)簽來(lái)放置對(duì)應(yīng)的slot,當(dāng)slot不存在的時(shí)候,slot標(biāo)簽內(nèi)寫的內(nèi)容就出現(xiàn)。
slot上面通過(guò)name屬性指定槽口名稱,然后使用的時(shí)候通過(guò)slot="槽口名稱"。
<div id = "app">
<aaa>
<!-- <h3>slot槽口插入的內(nèi)容</h3> -->
<p slot = "s1">在上面的內(nèi)容</p>
<p slot = "s2">在下面的內(nèi)容</p>
</aaa>
</div>
<template id="aaa">
<div class = "aaa">
<slot name = "s1"></slot>
<p>我是aaa組件</p>
<slot name = "s2"></slot>
</div>
</template>

slot插槽讓我們?cè)谠心0娴幕A(chǔ)上,定制更加多樣化的組件。
作用域插槽
當(dāng)我們想在父組件中訪問(wèn)子組件內(nèi)部的一些數(shù)據(jù)時(shí),就需要在子組件內(nèi)部的<slot>元素上動(dòng)態(tài)綁定一個(gè)自定義屬性,將數(shù)據(jù)傳遞到自定義屬性上,通過(guò)slot傳遞給父組件使用。
<slot :teacher="teacher"></slot>
綁定到<slot>元素上的屬性我們稱之為slot props。現(xiàn)在,在父組件中我們可以通過(guò)slot-scope給包含所有插槽 prop 的對(duì)象命名為prop,之后就可以通過(guò)prop來(lái)使用子組件中的數(shù)據(jù)了。
<template slot-scope="prop">
老師姓名:{{prop.teacher.name}} 老師年齡:{{prop.teacher.age}}
</template>

v-slot
v-slot指令自 Vue 2.6.0 起被引入,提供更好的支持slot和slot-scope特性的 API 替代方案。在接下來(lái)所有的 2.x 版本中slot和slot-scope特性仍會(huì)被支持,但已經(jīng)被官方廢棄,且不會(huì)出現(xiàn)在 Vue 3 中。
現(xiàn)在我們使用 v-slot 重構(gòu)上面的代碼:
<template v-slot:default="prop">
老師姓名:{{prop.teacher.name}} 老師年齡:{{prop.teacher.age}}
</template>
一個(gè)不帶 name 的 <slot> 出口會(huì)帶有隱含的名字“default”,使用時(shí)可以簡(jiǎn)化為v-slot="prop“。
具名槽口
子組件中通過(guò)name屬性給槽口設(shè)定名稱
<slot name="student" :student='student'></slot>
父組件中通過(guò)v-slot:名稱的方式來(lái)使用具名槽口
<template v-slot:student="prop">
學(xué)生姓名:{{prop.student.name}} 學(xué)生年齡:{{prop.student.age}}
</template>
當(dāng)我們?cè)诟附M件中多次調(diào)用子組件時(shí),可以通過(guò)設(shè)置不同的樣式,來(lái)設(shè)定子組件中數(shù)據(jù)的展示形式。
父子組件通信案例
通過(guò)屬性綁定和v-slot我們也可以在子組件中循環(huán)渲染父組件中的數(shù)據(jù)
首先我們?cè)诟附M件中定義一組數(shù)據(jù)
data(){
return{
listData:[
{
name:"Tome",
job:"web前端"
},
{
name:"Lily",
job:"java"
}
]
}
}
將數(shù)據(jù)通過(guò)屬性綁定的方式傳遞給子組件Home,并且設(shè)定一個(gè)v-slot插槽對(duì)象名稱,這時(shí)候插槽內(nèi)部就可以通過(guò)prop來(lái)訪問(wèn)數(shù)據(jù)
<Home :data = "listData" v-slot = "prop">
在Home組件中接收父組件傳遞過(guò)來(lái)的data
props:{
data:{
type:Array,
required:true
}
}
將data傳遞到slot的自定義屬性list中
<template>
<div class="home">
<slot :list = "data"></slot>
</div>
</template>
將Child組件插到Home組件的slot槽口中,并且Child組件可以通過(guò)prop.list來(lái)循環(huán)渲染數(shù)據(jù),并且將item通過(guò)屬性綁定的方式傳遞給Child
<Child v-for = "(item,index) in prop.list" :key = index :data = "item"></Child>
在Child組件中接收Home傳遞過(guò)來(lái)的data
props:{
data:{
type:Object,
required:true
}
}
并且在頁(yè)面中通過(guò)key名來(lái)渲染數(shù)據(jù)
<div class="home">
<p>{{data.name}}</p>
<p>{{data.job}}</p>
</div>
渲染結(jié)果:
