Skip to content

Vue 具名插槽 (Named Slots) 詳解:輕鬆管理元件中的多個預留位置

Vue 3 具名插槽:v-slot:name 與 #name

當您開發的 Vue 元件結構較為複雜(例如:包含頁首、頁尾與側邊欄的 Layout 元件)時,單一的 預設插槽 已不足夠。這時就需要使用 具名插槽 (Named Slots) 來精準指定內容的填入位置。

使用具名插槽,您不需要擔心 HTML 的先後順序或 CSS 版面配置,只要將內容分配給對應的名稱,子元件就會自動將它們安置在正確的預定義位置。

具名插槽實作步驟

子元件:定義具名插槽 name

元件中分別給予 <slot> 定義唯一的 name 屬性,例如:footextra

vue
<!-- /components/Card.vue -->
<template>
  <div class="card">
    <div class="card-head">
      <img class="card-image" src="https://picsum.photos/320/180" alt="">
    </div>
    <div class="card-body">
      <h2 class="card-title">卡片標題</h2>
      <p class="card-description">
        卡片描述~卡片描述~卡片描述~卡片描述~片描述~
      </p>
    </div>
    <div class="card-foot">
      <slot name="foot"></slot>
    </div>
    <div class="card-extra">
      <slot name="extra"></slot>
    </div>
  </div>
</template>

父元件:使用 v-slot# 語法傳入內容

在父元件呼叫時,必須使用 <template> 標籤並配合 v-slot 指令來對準目標插槽。

標籤中加入指定插槽的名稱,指定名稱的方式有二:

  • 標準語法v-slot:foot
  • 簡寫語法#foot
vue
<!-- /views/Slot.vue -->
<template>
  <card>
    <template #foot>
      <input type="button" value="click">
    </template>
  </card>
</template>

v-slot 只能寫在兩個地方

v-slot# 只能出現在 元件標籤<template> 標籤 上。寫在一般的 <div> 上不會生效,這也是為什麼具名內容都要用 <template> 包起來。

與預設插槽混用

未被 <template> 包起來的內容,會自動歸入名為 default 的預設插槽:

vue
<template>
  <Card>
    <!-- 這段沒有指定名稱,會進入 default 插槽 -->
    <p>我是主要內容</p>

    <template #foot>
      <button>送出</button>
    </template>
  </Card>
</template>

模板一旦同時存在具名內容,建議把預設內容也 明確寫成 <template #default>,讓每段內容的歸屬一目瞭然,也避免日後有人在中間插入節點時發生誤判。

渲染順序由誰決定?

這是具名插槽最方便的一點:父元件的撰寫順序完全不影響畫面順序

vue
<template>
  <Card>
    <!-- 雖然 foot 寫在前面…… -->
    <template #foot><button>送出</button></template>
    <template #extra><small>備註</small></template>
  </Card>
</template>

實際位置仍以子元件模板中 <slot> 出現的地方為準。版面配置的責任留在子元件,父元件只負責提供內容,這正是 插槽帶來的關注點分離

為什麼要使用具名插槽?

結構化版面配置

讓元件的內部結構(HTML/CSS)由子元件控制,而具體內容(數據/按鈕)由父元件決定。

語意清晰

透過 foot、header、sidebar 等名稱,程式碼的閱讀性大幅提升。

靈活性提升

父元件可以選擇性地填入部分插槽,未填入的部分則可以顯示子元件設定的預設內容。

若希望 沒填內容時連外層的包裝標籤都不要出現,可以搭配 條件插槽;若插槽名稱需要由變數決定,則可參考 動態插槽

常見問題

v-slot 與 # 有什麼差別?

沒有功能差別,#v-slot 的縮寫。v-slot:foot 等於 #foot,實務上多數專案採用縮寫寫法。

具名插槽一定要包在 template 標籤裡嗎?

是的,v-slot 只能寫在元件標籤或 <template> 標籤上。要把內容指定給某個具名插槽,就必須用 <template> 搭配 v-slot# 語法包起來。

父元件內容的撰寫順序會影響畫面順序嗎?

不會。畫面順序完全由子元件模板中 <slot> 的位置決定,父元件即使把頁尾內容寫在最前面,仍然會渲染在子元件安排的位置。

具名插槽可以和預設插槽混用嗎?

可以。沒有被 <template> 包起來的內容會自動歸入預設插槽,但當模板同時存在具名內容時,建議把預設內容也用 <template #default> 明確包起來,避免歸屬混淆。

父元件沒有填某個具名插槽會怎樣?

該插槽會顯示子元件寫的預設內容,若沒有預設內容就什麼都不渲染。但包在外層的 HTML 標籤仍然存在,若連標籤都想移除,需要搭配 條件插槽 的寫法。

延伸閱讀