本次嘗試一下,將知識講給別人聽的學習方法。
什麼是插槽
我們在引用組件時想要對組件樣式作出一些修改,這種情況比較適合使用插槽,否則不得不再寫一個代碼重複度高的組件或者將各種代碼都塞到一個組件中。
插槽簡單示例
我們引用組件,在標籤內寫入一些html代碼
<navigation-link url="/profile">
Your Profile
</navigation-link>
正常情況下這樣只會引用組件,標籤內的內容不會被渲染。
我們需要在組件中添加一個標籤"slot",這個標籤渲染後將被替換爲在父組件引用子組件的標籤中的代碼。如下:
<template>
<a v-bind:href="url" class="nav-link" >
<slot></slot>
</a>
</template>
渲染爲
<a v-bind:href="url" class="nav-link" >
Your Profile
</a>
插槽的編譯作用域(數據的調用範圍)
插槽中的代碼在正常情況下只能訪問所在實例的數據,而不能訪問要調用的組件中的數據。
<navigation-link url="/profile">
Logged in as {{ user.name }}
</navigation-link>
本例中只能訪問組件引用標籤所在實例中的user,若沒有則爲undefined
後備內容
"slot"標籤內可以寫html代碼,當插槽內沒有內容時會將"slot"標籤內的代碼渲染,否則不會渲染。
具名插槽
我們有時需要將引用組件的標籤中不同的代碼放在組件中不同的位置,這時候就要分別給插槽中代碼和slot標籤都命名。
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
slot有一個屬性name可以用來給slote命名
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
組件引用標籤中的內容可以用v-slot用來定義想要將代碼添加到組件的哪一個slot中(將代碼用template括起來)。
注意:一般v-slot只能放在template標籤上,當組件標籤中的代碼只提供給默認插槽時,可以在組件標籤上使用。
補充:
所有未被特殊命名的內容都會被歸爲默認插槽,默認插槽也有名子,即v-slot:default。
一個不帶 name 的slot會默認帶上default。
測試發現當給template用v-slot:default時,未被匹配的代碼不會再提供給默認slot,用slot="default"時,則未被匹配的仍被渲染。
作用域插槽
有時我們需要讓組件引用標籤中的代碼訪問組件中的數據,即父組件訪問子組件的數據。
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
如上,在子組件中的slote標籤上用v-bind來綁定要傳輸的數據。
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
在父級作用域中,v-slot:default="slotProps"這樣的格式來獲取子組件中傳輸的數據。獲取的屬性都將作爲slotProps的屬性被訪問。
只有默認插槽的縮寫語法
當只有默認插槽時,可以直接用v-slot=“slotProps”(直接添加在組件引用標籤上)來接收數據。
注意:這樣的寫法不能與具名插槽混用。
解構插槽
可以用解構賦值的方法接收指定的數據,如獲取user
<current-user v-slot="{ user }">
{{ user.firstName }}
</current-user>
也可以重命名
<current-user v-slot="{ user: person }">
{{ person.firstName }}
</current-user>
你甚至可以定義後備內容,用於插槽 prop 是 undefined 的情形:
<current-user v-slot="{ user = { firstName: 'Guest' } }">
{{ user.firstName }}
</current-user>
縮寫
v-slot:head = #head
廢棄語法
具名插槽
<base-layout>
<template slot="header">
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template slot="footer">
<p>Here's some contact info</p>
</template>
</base-layout>
在template上使用slot,用以指定代碼要傳給那個插槽,
與v-slot不同的是,slot可以用在普通html元素上。
作用域插槽slot-scope
同樣用於父作用域調用子組件數據的情況。
<slot-example>
<template slot-scope="slotProps">
{{ slotProps.msg }}
</template>
</slot-example>
與v-slot:="slotProps"不同的是,slot-scope="slotProps"可以寫在非template元素上。