插槽,也就是slot,是組件的一塊HTML模板,這塊模板顯示不顯示、以及怎樣顯示由父組件來決定。 實際上,一個slot最核心的兩個問題在這里就點出來了,是顯示不顯示和怎樣顯示。
由於插槽是一塊模板,所以,對於任何一個組件,從模板種類的角度來分,其實都可以分為非插槽模板和插槽模板兩大類。
非插槽模板指的是html模板,比如‘div、span、ul、table’這些,非插槽模板的顯示與隱藏以及怎樣顯示由組件自身控制;
插槽模板是slot,它是一個空殼子,因為它的顯示與隱藏以及最后用什么樣的html模板顯示由父組件控制。但是插槽顯示的位置卻由子組件自身決定,slot寫在組件template的什么位置,父組件傳過來的模板將來就顯示在什么位置。
1、插槽內容
vue實現了一套內容分發的api,將 slot 元素作為承載內容分發的出口。
插槽內可以包含任何模板代碼,包括html,以及其他組件。
如果組件內沒有一個 slot 元素,那么該組件起始標簽和結束標簽之間的任何內容都會被拋棄。
2、編譯作用域
規則:父級模板里的所有內容都是在父級作用域中編譯的;子模板里的所有內容都是在子作用域中編譯的。
3、后備內容
有時為一個插槽設置具體的后備 (也就是默認的) 內容是很有用的,它只會在沒有提供內容的時候被渲染。
很簡單,就是默認值的概念。<slot>Submit</slot>
4、具名插槽
需要多個插槽的情況,slot 元素有一個特殊的屬性:name,用來定義額外的插槽。一個不帶 name
的 <slot>
出口會帶有隱含的名字“default”。
在向具名插槽提供內容的時候,我們可以在一個 <template>
元素上使用 v-slot
指令,並以 v-slot
的參數的形式提供其名稱:
<template v-slot:footer>
<p>Here's some contact info</p> </template>
現在 <template>
元素中的所有內容都將會被傳入相應的插槽。任何沒有被包裹在帶有 v-slot
的 <template>
中的內容都會被視為默認插槽的內容。
注意:v-slot只能添加在一個 <template>
上(有一種例外),這一點和已廢棄的slot特性不同
5、作用域插槽
<current-user>
{{ user.firstName }}
</current-user>
上述代碼不會正常工作,因為只有 <current-user>
組件可以訪問到 user
而我們提供的內容是在父級渲染的。為了讓 user
在父級的插槽內容可用,我們可以將 user
作為 <slot>
元素的一個特性綁定上去:
<span>
<slot v-bind:user="user"> {{ user.lastName }} </slot> </span>
綁定在 <slot>
元素上的特性被稱為插槽 prop。現在在父級作用域中,我們可以給 v-slot
帶一個值來定義我們提供的插槽 prop 的名字:
<current-user>
<template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template> </current-user>
我們選擇將包含所有插槽 prop 的對象命名為 slotProps
,但你也可以使用任意你喜歡的名字。
(1)獨占默認插槽縮寫方式:
當被提供的內容只有默認插槽時,組件的標簽才可以被當作插槽的模板來使用。這樣我們就可以把 v-slot
直接用在組件上,這也就是上面說的例外情況
<current-user v-slot:default="slotProps"> {{ slotProps.user.firstName }} </current-user>
注意:只要出現多個插槽,請始終為所有的插槽使用完整的基於 <template>
的語法
(2)解構插槽:
作用域插槽的內部工作原理是將你的插槽內容包括在一個傳入單個參數的函數里,這意味着 v-slot
的值實際上可以是任何能夠作為函數定義中的參數的 JavaScript 表達式,所以可以利用ES6的解構來傳入參數
<current-user v-slot="{ user: person }"> {{ person.firstName }} </current-user>
解構:v-slot="{ user }"
重命名:v-slot="{ user: person }"
定義默認值:v-slot="{ user = { firstName: 'Guest' } }"
6、動態插槽名
<template v-slot:[dynamicSlotName]> ... </template>
7、縮寫
v-slot:header
可以被重寫為 #header
8、其他示例
主要來自官網學習整理:https://cn.vuejs.org/v2/guide/components-slots.html