一 插槽目的與作用
Vue 將 <slot>
元素作為承載分發(fā)內(nèi)容的出口芥牌。
插槽就是子組件中的提供給父組件使用的一個占位符仍侥,用<slot></slot> 表示稽物,父組件可以在這個占位符中填充任何模板代碼鸳惯,如 HTML、組件等瘾腰,填充的內(nèi)容會替換子組件的<slot></slot>標(biāo)簽皆的。
插槽覆履,其實(shí)就相當(dāng)于占位符蹋盆。
二 插槽基礎(chǔ)使用
1、在子組件中放一個占位符
<template>
<div>
<h1>今天天氣狀況:</h1>
// 設(shè)置插槽
<slot></slot>
</div>
</template>
<script>
export default {
name: 'child'
}
</script>
2硝全、在父組件中給這個占位符填充內(nèi)容
<template>
<div>
<div>使用slot分發(fā)內(nèi)容</div>
<div>
<child>
// 分發(fā)給子組件的插槽內(nèi)容
<div style="margin-top: 30px">多云栖雾,最高氣溫34度,最低氣溫28度伟众,微風(fēng)</div>
</child>
</div>
</div>
</template>
<script>
import child from "./child.vue";
export default {
name: 'father',
components:{
child
}
}
</script>
3析藕、展示效果
當(dāng)組件渲染的時候,<slot></slot> 將會被替換為父組件傳入的內(nèi)容凳厢。該內(nèi)容可以包含任何模板代碼账胧,包括 HTML,甚至其它的組件先紫。
如果子組件的 template 中沒有包含一個 <slot> 元素治泥,則該組件起始標(biāo)簽和結(jié)束標(biāo)簽之間的任何內(nèi)容都會被拋棄。
即 如果子組件沒有使用插槽遮精,父組件如果需要往子組件中填充模板或者h(yuǎn)tml, 是沒法做到的居夹。
三 深入了解插槽使用
<1> 插槽的編譯作用域
父級模板里的所有內(nèi)容都是在父級作用域中編譯的;子模板里的所有內(nèi)容都是在子作用域中編譯的本冲。
<navigation-link url="/profile">
Clicking here will send you to: {{ url }}
<!--
這里的 `url` 會是 undefined准脂,因?yàn)槠?(指該插槽的) 內(nèi)容是
_傳遞給_ <navigation-link> 的而不是
在 <navigation-link> 組件*內(nèi)部*定義的。
-->
</navigation-link>
<2> 給插槽的slot位置設(shè)置默認(rèn)值
給插槽設(shè)置具體的后備 (也就是默認(rèn)的) 內(nèi)容檬洞,它只會在沒有提供內(nèi)容的時候被渲染狸膏。
例如,
某子組件<submit-button>中的<button> 內(nèi)絕大多數(shù)情況下都渲染文本“Submit”。為了將“Submit”作為后備內(nèi)容添怔,我們可以將它放在 <slot> 標(biāo)簽內(nèi):
<button type="submit">
<slot>Submit</slot>
</button>
當(dāng)在一個父級組件中使用 <submit-button> 并且不提供任何插槽內(nèi)容時,后備內(nèi)容“Submit”將會被渲染
當(dāng)提供內(nèi)容:
<submit-button>
Save
</submit-button>
則這個提供的內(nèi)容將會被渲染從而取代后備內(nèi)容:
<button type="submit">
Save
</button>
<3> v-slot具名插槽與匿名插槽
跟 v-on 和 v-bind 一樣湾戳,v-slot 也有縮寫, 為#,即把(v-slot:) 替換為字符 #澎灸。例如 v-slot:header 可以被重寫為 #header院塞。
該縮寫只在其有參數(shù)的時候才可用, 如果希望使用縮寫的話,必須始終以明確插槽名取而代之性昭。
具名插槽其實(shí)就是給插槽取個名字拦止。一個子組件可以放多個插槽,而且可以放在不同的地方,而父組件填充內(nèi)容時汹族,可以根據(jù)這個名字把內(nèi)容填充到對應(yīng)插槽中萧求。
vue給<slot> 元素定義有一個特殊的屬性:name。這個屬性可以用來定義插槽 (即給它取名)顶瞒。
匿名插槽夸政,又可以叫它單個插槽或者默認(rèn)插槽。與具名插槽相對榴徐,它不需要設(shè)置name屬性守问。(它隱藏的name屬性為default。)
舉例,
定義子組件
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
父組件使用插槽
父組件填充內(nèi)容, 父組件通過 v-slot:[name] 的方式指定到對應(yīng)的插槽中
即父組件通過在template上寫v-slot:name來使用具名插槽
父組件在向具名插槽提供內(nèi)容的時候坑资,我們可以在一個 <template> 元素上使用 v-slot 指令耗帕,并以 v-slot 的參數(shù)的形式提供其名稱:
<base-layout>
// v-slot:header 可以被重寫為 #header
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
// 這里可以將template標(biāo)簽去掉,單純放內(nèi)容也可以 或者單單去掉v-slot:default
<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
現(xiàn)在 <template> 元素中的所有內(nèi)容都將會被傳入相應(yīng)的插槽。任何沒有被包裹在帶有 v-slot 的 <template> 中的內(nèi)容都會被視為默認(rèn)插槽的內(nèi)容袱贮。
注意 v-slot 只能添加在 <template> 上 (只有一種例外情況 : 被廢棄的slot=‘name’)
<4> 作用域插槽 -- 插槽 prop
作用域插槽其實(shí)就是可以傳遞數(shù)據(jù)的插槽仿便。
它本質(zhì)上是vue為了將子組件中的數(shù)據(jù)方便給父組件的插槽內(nèi)容中使用, 從而給 <slot> 元素設(shè)置一個屬性。
將該屬性綁定上slot中, 從而父組件可訪問子組件的數(shù)據(jù)攒巍。
綁定在 <slot> 元素上的 attribute 被稱為插槽 prop嗽仪。
子組件中的一些數(shù)據(jù)想在父組件中使用,必須通過規(guī)定的方法來傳遞柒莉。在官方文檔中提出了一條規(guī)則闻坚,父級模板里的所有內(nèi)容都是在父級作用域中編譯的。子模板里的所有內(nèi)容都是在子作用域中編譯的常柄。如果你在父組件直接使用子組件中的值鲤氢,是會報錯的。
(01)匿名插槽的作用域插槽
為了讓 子組件中的數(shù)據(jù) 在父級的插槽內(nèi)容中可用西潘,我們可以將 數(shù)據(jù) 作為 元素的一個特性綁定上去:
語法:v-bind:users="user"
舉例,
子組件設(shè)置slot, 并綁定數(shù)據(jù)
為了讓 user 在父級的插槽內(nèi)容中可用卷玉,我們可以將 user 作為 <slot> 元素的一個 attribute 綁定上去:
<template>
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
</template>
綁定在 <slot> 元素上的 attribute 特性(v-bind:users=“user”)被稱為插槽 prop。現(xiàn)在在父級作用域中喷市,我們可以使用帶值的 v-slot 來定義我們提供的插槽 prop 的名字:
語法:v-slot:default="隨意取的名字" // default可省略相种,簡寫為v-slot="隨意取的名字"
父組件中通過插槽prop屬性使用子組件的數(shù)據(jù)
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
在這個例子中,我們選擇將包含所有插槽 prop 的對象命名為 slotProps品姓,但你也可以使用任意你喜歡的名字寝并。
注意:
父組件中的slotProps可以是隨意取的。
子組件中users是隨意取的腹备,與之對應(yīng)的是父組件中的users衬潦。
子組件中的user為數(shù)據(jù)。
(02) 具名插槽的作用域插槽
與匿名插槽同理植酥,只需要把default替換成插槽的name值即可镀岛。
舉例,
子組件
<template>
<div class="hello">
<div class='slotLeft'>
<slot name='helloWorld' v-bind:users="user"></slot>
</div>
</div>
</template>
父組件
<template>
<div class="home">
<HelloWorld>
<template v-slot:helloWorld="slotProps">
<h1>{{slotProps.users.name}}</h1>
</template>
</HelloWorld>
</div>
</template>
注意:
默認(rèn)插槽的縮寫語法不能和具名插槽混用弦牡,因?yàn)樗鼤?dǎo)致作用域不明確。
另漂羊,slot-scope寫法在2.6之后已廢棄驾锰,作用與上面相同,在此不做解釋走越。
上面的寫法是不是覺得有些麻煩椭豫?別著急,我們來看一看解構(gòu)插槽 Prop旨指。
<5> 解構(gòu)插槽 Prop
作用域插槽的內(nèi)部工作原理是將你的插槽內(nèi)容包括在一個傳入單個參數(shù)的函數(shù)里:
function (slotProps) {
// 插槽內(nèi)容
}
這意味著 v-slot 的值實(shí)際上可以是任何能夠作為函數(shù)定義中的參數(shù)的 JavaScript 表達(dá)式赏酥。所以在支持的環(huán)境下 (單文件組件或現(xiàn)代瀏覽器),你也可以使用 ES2015 解構(gòu)來傳入具體的插槽 prop淤毛。
語法:v-slot="{ users }"
舉例,
子組件
<template>
<div class="hello">
<div class='slotLeft'>
<slot v-bind:users="user"></slot>
</div>
</div>
</template>
父組件
舉例1
<template>
<div class="home">
<HelloWorld>
<template v-slot="{ users }">
<h1>{{users.name}}</h1>
</template>
</HelloWorld>
</div>
</template>
舉例2
<current-user v-slot="{ user }">
{{ user.firstName }}
</current-user>
<6> 插槽prop的重命名
這樣可以使模板更簡潔今缚,尤其是在該插槽提供了多個 prop 的時候算柳。它同樣開啟了 prop 重命名等其它可能低淡,例如將 user 重命名為 person:
// 在父組件中
舉例1
<current-user v-slot="{ user: person }">
{{ person.firstName }}
</current-user>
舉例2
<template>
<div class="home">
<HelloWorld>
<template v-slot="{ users:person }">
<h1>{{person.name}}</h1>
</template>
</HelloWorld>
</div>
</template>
<7> 插槽prop的后備內(nèi)容
插槽prop定義后備內(nèi)容,用于插槽 prop 是 undefined 的情形
<current-user v-slot="{ user = { firstName: 'Guest' } }">
{{ user.firstName }}
</current-user>
待補(bǔ)充
<8> ### 獨(dú)占默認(rèn)插槽的縮寫語法
<9> 動態(tài)插槽名
參考鏈接:
https://blog.csdn.net/Oralinge/article/details/103896320
https://blog.csdn.net/bobozai86/article/details/105473445
-- 2021.10.12