前言
Photo by Hanna Balan on Unsplash
v-slot 又是一篇沒有在vue-pattern的章節,但是真的很常遇到&其他章節也有使用,自己閱讀的時候倒是先到後面章節卡關後才回頭來完整查找v-slot的用法。
- Vue官方文件-components-slots
- 範例程式碼
- Vue v-slot tutorial with examples
- 複用元件的好幫手:Vue Slots(v-slot、Scoped Slots)
注: 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,因此會特地在這篇中放入新舊語法,希望能夠幫助正在閱讀這篇的你,減少一些學習上的冤枉多點時間下班打電動。