複用元件的好幫手:Vue Slots(v-slot、Scoped Slots)

介紹 Vue Slots 用法以及實際範例。

Lai
UnaLai
6 min readDec 30, 2019

--

Vue Slots

為了讓元件保持彈性, v-slot 、Scoped Slots 真的好好用也好常遇到 🤩。決定回頭再把 Slot 文件看一遍,整理一下思緒記錄下來。

Outline
* Slot 介紹
* Fallback Content 預備內容
* Named Slots 具名插槽
* Compilation Scope 編譯作用域
* Scoped Slots 作用域插槽
* 看看真實範例 - 以 BoostrapVue Table 為例
* 後記
* 參考來源

# Slot 介紹

Slot 如同它的字面翻譯「插槽」。子元件預留了一個空間(槽),讓父元件插入內容。讓元件的複用變得更加彈性。看一個簡單的例子,快速認識一下 Slot。

假設我有一個簡單的子元件 mybutton。

父元件使用 mybutton 元件,並傳入按鈕文字 “送出”。

畫面結果如下:

子元件 mybutton 預留了一個空間 slot,讓父元件插入內容“送出”,顯示於預留空間。

# Fallback Content

如果大部分的情況都是顯示 “送出”,只有少部分需要顯示其他文字或是預防使用 mybutton 時,忘記插入按鈕文字,這時候可以使用 Fallback Content 當作預備內容。

於子元件 mybutton 放入 <slot></slot> 中放入預備內容:

當父元件未插入任何內容時,mybutton 按鈕文字為送出。若有一個畫面需要的文字為儲存時,父元件插入按鈕文字 “儲存”,則 mybutton 按鈕文字為儲存。

# Named Slots

當插入內容及預留空間只有一個時,可以很輕易的辨識。但當父元件插入多個內容時,子元件該如何辨識,並放置正確內容於對的預留空間呢?

這時候就要使用 Named Slots 對插入內容及預留空間進行命名了。

假設子元件 product 需要顯示三個資料:名稱、價格、材質。於子元件中,預留這三筆資料的位置,並使用屬性 name 表示預留空間的名稱。

於父元件中,對具名的預留空間插入內容時,需使用 template 元素搭配 v-slot 表明。

畫面結果如下:

# Compilation Scope

父元件對子元件所插入的內容,都是在父元件作用域當中編譯的。例如上述範例中的”中高領刷毛上衣”,為父元件提供,亦能夠使用父元件當中的變數。

若想要使用子元件中的內容,需透過 solt prop 取得,也就是接下來要提到的 Scoped Slots

# Scoped Slots

接續上面範例,假設折扣資料在子元件裡,而在父元件提供插入內容時,希望能計算出折扣價。

這時,我們可以在子元件中,將資料綁定 (v-bind) 給 slot。

上圖程式碼指的是,綁定一個名為 discount 的資料給名為 price 的 slot 內容,綁定的資料為子元件當中的 discount 變數。

接著在父元件中,利用 v-slot 指令接出來用。命名為 slotProps,這邊命名可以依照需求,語意化自訂。

畫面結果如下:

官方文件中有提到 Scoped Slots 的內部原理,是將父元件傳入的內容放入一個擁有單個參數的函式裡,而單個參數 slotProp 即為子元件 props 給父元件的資料。

function (slotProps) {
// 父元件傳入的插槽内容
}

因此我們可以使用 ES6 解構賦值語法,重新改寫一下父元件 slot prop 的寫法,使之更為簡潔。

如為單個 slot 時,可以使用縮寫語法,假設我們只有一個只有 price 資料。則 slot 不需命名,預設為 default。我們就可以將上述情境改寫為以下。

子組件:

父組件:

亦可以省略 default :

# 看看真實範例

許多套件為了讓使用者能夠更彈性化的使用,常常利用 Slot 開放部分區塊,讓使用者可以客製化內容,例如BootstrapVue、Element UI。

BootstrapVue 當中的 table 元件即為一個很好的範例。使用 table 時,因應需求,可能需要在 table 欄位中,進行客製化顯示,例如顯示 checkbox 等。

BootstrapVue 自定義命名規則來命名 slot,例如想更改表身中的 name 欄位時,命名為 cell(name) 。在父層使用 table 元件並插入資料的寫法則為:

上述程式碼使用 v-slot 語法,參數 cell(name) 為插入資料給 slot 時,該 slot 的名稱,而後接著的 data,即為 slot prop,使用 Scoped Slots 的方式得到可用資料 data。如上一章節內容,這邊可以利用解構賦值,把資料寫的更為明確。

表頭、表尾及其他相關用法原理皆與表身所用的方式一樣。可以到官網 table 元件中的 Custom data rendering 章節即時編輯玩玩看。

# 後記

slot 常用於開發中,更是設計複用 component 時的好幫手。尤其當複用 component 在某個情境下,有些微不同時,這時候就可以使用 Scoped Slots 的方式,開放客製化區塊,使複用 component 更為彈性。使用套件寫好的 component 時,也常常可以看到 Scoped Slots 的寫法,這時候記得可以使用解構賦值,使參數使用起來更為簡潔,也是非常重要的。

以上是今天的分享,有任何問題都歡迎留言指教,謝謝 😊

# 參考來源

  1. Vue.js Slots
  2. BootstrapVue

--

--

Lai
UnaLai
Editor for

我是一名前端工程師,我熱愛學習與分享 ❤︎