今天將延續昨天的內容,繼續介紹插槽 Slots 將父元件的內容渲染在子元件中指定的位置
若要根據插槽是否存在來渲染內容,可以使用 $slots 屬性和 v-if 指令。
以下是官方文件的範例
<template>
<div class="card">
<div v-if="$slots.header" class="card-header">
<slot name="header" />
</div>
<div v-if="$slots.default" class="card-content">
<slot />
</div>
<div v-if="$slots.footer" class="card-footer">
<slot name="footer" />
</div>
</div>
</template>
v-slot 可以和動態指令參數一起搭配使用,透過定義動態的插槽名稱來切換 slot 的位置。
以下是官方文件的範例
<base-layout>
<template v-slot:[dynamicSlotName]>
... //寫入插植內容
</template>
<!-- 縮寫為 -->
<template #[dynamicSlotName]>
...//寫入插植內容
</template>
</base-layout>
渲染作用域
插槽的內容無法訪問子元件的資料,也就是說父元件模板中的表達式,只能訪問父元件的作用域;而子元件模板中的表達式,只能訪問子元件的作用域。
在某些情況下,插槽的內容要同時使用父元件和子元件區域內的資料,透過使用作用域插槽,子元件可以將資料傳遞給父元件的插槽內容,父元件可以使用這些資料來定義要渲染的內容,最終這些內容會被渲染到子元件的 slot 位置。
以下是官方文件的範例
在子元件 MyComponent 檔案中:
<script setup>
const greetingMessage = 'hello'
</script>
<template>
<div>
<slot :text="greetingMessage" :count="1"></slot>
</div>
</template>
在父元件檔案中,將子元件傳入插槽的 props 作為 v-slot 指令的值,並且可以在插槽內的表達式中訪問。
<script setup>
import MyComponent from './MyComponent.vue'
</script>
<template>
<MyComponent v-slot="slotProps">
{{ slotProps.text }} {{ slotProps.count }}
</MyComponent>
</template>
最後呈現出來的結果為 hello 1
若是具名插槽,則透過 v-slot:name="slotProps" 來接收 props。
以下是官方文件的範例
在子元件 MyComponent 檔案中:
<slot name="header" message="hello"></slot>
在父元件檔案中:
<MyComponent>
<template #header="headerProps">
{{ headerProps }}
</template>
</MyComponent>
除了 name 屬性之外的其他屬性都會被當作插槽 props 傳遞給父元件,因此最終 headerProps 的結果是 { message: 'hello' }。
https://book.vue.tw/CH2/2-4-slots.html
https://zh-hk.vuejs.org/guide/components/slots.html
https://www.nielsen.tw/vue/slot/
https://christine52jesus.medium.com/vue3-%E7%B3%BB%E5%88%97-%E4%BB%80%E9%BA%BC%E6%98%AF%E6%8F%92%E6%A7%BD-slots-20a192537b05