用途
將每個功能都包成component時,很方便可以直接拿來重複使用。
但有時總會有一些想要一些不同,總不能再額外寫一個很像的component,這樣就失去了component的重複使用性了。
這時可以透過<slot>
標籤,component裡面放一些自定義的文字或內容。slot
標籤可以想像成是在component裡面挖了一個洞,將你要的內容塞進去。
這邊有兩種挖洞的方式,分別是單個插槽(Single Slot)與具名插槽(Named Slots)。
先來看一個沒有使用slot
的範例
HTML部分:
1 | <h2>沒有插槽可替換的狀態</h2> |
Javascript部分:
1 | Vue.component('no-slot-component', { |
結果如圖,只有呈現template裡面原本的內容 “這沒有插槽”。
而”替換的內容”卻沒有出現。
這是為什麼呢?
還記得生命週期中有個template的橋段
如果有template就會執行template 沒有就innerHTML
因此,當宣告component時有指定template的話,
在使用
但有個例外,那就是使用slot
標籤。
單個插槽(Single Slot)
在template中加入<slot></slot>
。
HTML部分:
1 | <h2>Slot 基礎範例</h2> |
Javascript部分:
1 | Vue.component('single-slot-component', { |
結果如圖,應該出現”如果沒有內容,則會顯示此段落。”
被取代為”使用這段取代原本的 Slot。”
在上面的範例如果在component裡沒有放其他內容,如下:
HTML部分:
1 | <h3>使用compoment slot裡default資料</h3> |
結果如圖,會直接採用component裡slot的default資料
具名插槽(Named Slots)
這時問題來了,如果想要在一個component裡挖很多洞放很多個slot
呢?
這時就會需要幫每一個slot
命名。
HTML部分:
1 | <h2>具名插槽</h2> |
Javascript部分:
1 | Vue.component('named-slot-component', { |
結果如圖,內容有順利被替換掉。
不過可以注意到的是,當有name的時候,畫面顯示的順序會依照
template內所定義的位置呈現,也就是說在引用component時裡面寫的順序調換不受影響,如下:
HTML部分:
1 | <h2>具名插槽</h2> |
以上範例的完整程式碼
v-slot寫法
在vue2.6版本時slot
出了新的寫法v-slot
我這邊試寫了一下,範例可以參考v-slot寫法的程式碼
裡面有幾個點需要注意一下
- v-slot 只能添加到
<template>
或自定義的component上,像是<div>
或<p>
就會錯誤。舊的寫法就沒有這個限制。 - v-slot的缩写是#
- 但建議若要使用v-slot就從頭到尾都用v-slot,若要用#就從頭到尾都用#
- 如果要使用
v-slot
要確認使用的vue的版本是否有支援,版本需2.6以上
編譯作用域(Compilation Scope)
編譯作用域是指編譯層級以所在範圍為主,也就是說父層的data由父層的data決定,子層的data由子層的data決定。
這邊用來兩個例子來說明
第一個範例:沒有使用slot
範例完整程式碼
HTML部分
1 | <div id="app"> |
Javascript部分
1 | // children component |
畫面呈現如下:
會這樣呈現的原因有兩個
- 剛剛提到生命週期的部分,在沒有使用
slot
的狀況下會直接讀取template裡的內容當模板渲染,因此<child></child>
會被無視,只呈現<div class="child"></div>
的內容 - 由於編譯作用域的原因,會讀取所在的component的data,所以
<div class="child"></div>
裡的msg是讀取子component的data
第二個範例:有使用slot
範例完整程式碼
HTML部分
1 | <div id="app"> |
畫面呈現如下:
會這樣呈現的原因
- 根據編譯作用域的原因,template中的第一個msg,會讀取子component的data
- 因為有使用
slot
,所以<slot><slot>
中會呈現<div>This "msg" is from parent: </div>
,由於<div>This "msg" is from parent: </div>
所在位置為根實體,所以會取得根實體data中的msg呈現
參考資料
- 五倍紅寶石-Vue.js 與 Vuex 前端開發實戰課程
- vue出一個電商網站
- vue中的插槽–slot和v-slot
- Vue.js: Slot