[03] v-slot ( slot, slot-scope )


Posted by m6fish on 2021-01-12

前言

Photo by Hanna Balan on Unsplash

v-slot 又是一篇沒有在vue-pattern的章節,但是真的很常遇到&其他章節也有使用,自己閱讀的時候倒是先到後面章節卡關後才回頭來完整查找v-slot的用法。

注: vue 2.6以後 v-slot 取代原本的 slot,slot-scope,下面敘述會包含新舊寫法
(以新寫法為主,舊寫法已廢棄但目前2021-1-12仍可使用)

主題

v-slot 基本

目的: 在子組件設計的時候預留空間(slot),讓使用的時候(父組件)可以塞入新的內容

  • 可以有很多個不同名稱的 slot
  • 子組件開slot的時候,可以先塞入預設值
  • 實際渲染根據子組件安排順序
// basic.vue 子組件
<div class="basic">
    <slot name="header">
        <h1>Here might be a User Name</h1>
    </slot>
    <!-- only one default slot -->
    <slot>
        <p>A paragraph for the main content.</p>
        <p>And another one.</p>
    </slot>
    <slot name="footer">
        <p>Here's some contact info</p>
    </slot>
</div>

Old:

// index.vue 父組件
<basic>
    <p>Hello Vue slot</p>
    <template slot="footer">
        <p>footer</p>
    </template>
    <template slot="header">
        <h1>Bulb</h1>
    </template>
</basic>

New:

// index.vue 父組件
<basic>
    <template v-slot:header>
        <h1>NewBulb</h1>
    </template>
    <p>Hello v-slot</p>
    <template v-slot:footer>
        <p>v-slot footer</p>
    </template>
</basic>

注: 如果子組件裏頭沒有 v-slot,父組件tag之間即使有提供內容,也不會出現任何東西

slot-scope

目的:提供子組件的資訊讓父組件使用

  • 子組件 v-bind/props 讓父組件可以存取子層的資料
  • 父組件可以使用 ES6 解構語法,少包一層
// card.vue 子組件
<div class="card">
    <p>name: {{user.name}}</p>
    <p>rank: {{user.rank}}</p>
    <slot v-bind="{salary: getSalary}"/>
</div>

Old:

// index.vue 父組件
<card v-bind="{user: userA}">
    <template slot="default" slot-scope="slotProps">
        {{ slotProps.salary }}
    </template>
</card>

New:

// index.vue 父組件
<card v-bind="{user: userB}">
    <template v-slot:default="{salary}">
        {{ salary }}
    </template>
</card>

動態 slot name

目的: 可以依照實際狀況,切換放入的slot

// 官網範例 父組件
<base-layout>
    <template v-slot:[dynamicSlotName]>
        ...
    </template>
</base-layout>

slot name 簡寫

目的: 語法糖,寫少一點code

  • # 取代 v-slot=
  • default slot 要寫完整名稱,不能用無名slot寫法 (e.g. #="{ salary }" 是錯誤的)
// index.vue 父組件
<basic>
    <template #header>
        <h1>NewBulb - Shorthand</h1>
    </template>
    <p>Hello v-slot Shorthand</p>
    <template #footer>
        <p>v-slot footer</p>
    </template>
</basic>

<card v-bind="{user: userB}">
    <template #default="{salary}">
        {{ salary }}
    </template>
</card>

總結

自己的記憶方式:

  • 子組件打洞(slot),父組件直接拿來用
  • slot 打洞, v-slot 接洞

現實中很多套件為了提供更彈性化的功能,都有使用這個語法。
而筆者自己在學習這塊部分的時候,覺得最容易搞混的是 v-slot / slot 在父組件或子組件的使用場合,而且再加上新舊語法交替,在資料查找上也下了不少功夫不少中文資源都還是舊語法Orz,因此會特地在這篇中放入新舊語法,希望能夠幫助正在閱讀這篇的你,減少一些學習上的冤枉多點時間下班打電動


#Vue #vue-pattern







Related Posts

關於 React 小書:React 評論功能(四):localStorage、命名與方法擺放順序

關於 React 小書:React 評論功能(四):localStorage、命名與方法擺放順序

系統架構 & 資料庫結構 筆記

系統架構 & 資料庫結構 筆記

JavaScript 執行環境與作用域

JavaScript 執行環境與作用域


Comments