Vue Slot 插槽完全指南:提高元件複用性與開發效率的關鍵技巧
Vue 的 slot (插槽) 是元件開發中極其重要的核心觀念。簡單來說,它就是元件中的 預留位置,是實作高度自定義元件的基礎。
當您開發一個通用元件(例如:按鈕 Button、彈窗 Modal、卡片 Card)時,無法預知未來內容的變化。這時,您可以預留一個洞,也就是使用 <slot> 標籤,讓父元件在呼叫時彈性填入內容。
<!-- 子元件:外殼由我決定 -->
<template>
<div class="card">
<slot></slot>
</div>
</template><!-- 父元件:內容由我決定 -->
<template>
<Card>這段內容會被填進上面的 slot</Card>
</template>為什麼開發者必須掌握 Vue 插槽 (Slots)?
在現代網頁開發中,使用插槽能帶來以下三大核心優勢:
極大化元件複用性 (Reusability)
您可以建立一個通用的外殼元件(例如:帶有陰影和邊框的卡片),而具體內容由各個頁面決定。透過 Slot,您只需要撰寫一次 CSS 和動畫邏輯,減少重複程式碼,讓專案更易於維護。
完美的關注點分離 (Separation of Concerns)
Slot 讓版面配置 (Layout) 與內容 (Content) 職責分明:
- 父元件:負責資料數據、商業邏輯與實際內容。
- 子元件:負責視覺結構、UI 樣式與交互框架。
提供靈活的 UI 內容注入
比起傳統使用 props 傳遞字串,Slots 的靈活性更高。您不僅可以傳入文字,還能在子元件中插入 複雜的 HTML 結構、SVG 圖示,甚至是 其他的 Vue 元件。
插槽與 props 該怎麼選?
初學時最常見的疑問是:內容用 props 傳不是也可以嗎?兩者的分界其實很清楚:
| 你要傳的東西 | 該用的方式 | 原因 |
|---|---|---|
| 資料,例如:標題文字、數量、是否停用 | props | 子元件需要拿它做邏輯判斷或格式化 |
| 畫面,例如:一段 HTML、圖示、另一個元件 | slot | 子元件不需要理解內容,只負責決定它出現在哪裡 |
| 使用者操作的結果需要通知父層 | emit | 資料流方向相反,由子層往父層送 |
一個實用的判斷句:如果這個值不會被子元件拿去做判斷,只是原封不動渲染出來,那它就該是插槽內容。
編譯作用域:插槽內容看得到誰的資料?
插槽有一條容易踩雷的規則:插槽內容是在父元件的作用域中編譯的。
<!-- 父元件 -->
<template>
<!-- ✅ userName 是父元件的資料,可以用 -->
<Card>{{ userName }}</Card>
<!-- ❌ internalData 是子元件內部的資料,這裡拿不到 -->
<Card>{{ internalData }}</Card>
</template>也就是說,父元件寫在標籤之間的內容,只看得到父元件自己的 響應式狀態。想跨越這道界線,就得靠下面要介紹的作用域插槽。
進階技巧:作用域插槽 (Scoped Slots) 的威力
除了基礎用法,作用域插槽 是邁向資深 Vue 開發者的必經之路。它允許子元件將內部數據回傳給父元件。
實際案例:想像一個資料列表元件,它負責抓取 API 數據並處理分頁,但您希望父元件來決定每一列資料的具體呈現方式,例如:顯示頭像或純文字。這就是作用域插槽發揮威力的最佳時機。
插槽家族一覽
整個插槽系列可以依 解決什麼問題 來理解:
- 基本插槽:只有一個洞,順便準備好預設內容。
- 具名插槽:多個洞,用名稱決定內容去哪裡。
- 作用域插槽:子元件把資料傳出來給父元件渲染。
- 具名作用域插槽:多個洞,而且每個洞都能帶資料出來。
- 條件插槽:父元件沒傳內容時,連外層包裝標籤都不要渲染。
- 動態插槽:用變數決定內容要塞進哪一個洞。
常見問題
Vue 的插槽是什麼?
插槽是子元件在模板中預留的位置,寫成 <slot> 標籤。父元件使用該元件時,寫在標籤之間的內容會被填進這個位置,因此同一個元件外殼可以搭配完全不同的內容。
什麼時候該用插槽、什麼時候該用 props?
傳的是 資料 就用 props,例如:標題文字、數量、是否停用。傳的是 畫面結構 就用插槽,例如:一段 HTML、圖示或另一個元件。判斷方式是問自己這個值需不需要被子元件拿去做邏輯判斷。
插槽可以塞入其他元件嗎?
可以。插槽內容能放文字、HTML 結構、SVG 圖示,也能放另一個 Vue 元件,而且這些內容是在 父元件的作用域 中編譯的。
插槽內容可以存取子元件的資料嗎?
預設不行。插槽內容在父元件的作用域編譯,只看得到父元件的資料。若需要用到子元件內部的資料,必須改用 作用域插槽,由子元件把資料綁到 <slot> 上傳出來。
一個元件可以有幾個插槽?
數量沒有限制。未命名的預設插槽只能有一個,其餘的用 name 屬性區分,就是 具名插槽,適合頁首、內容、頁尾這類多區塊的版面元件。