點燈坊

失くすものさえない今が強くなるチャンスよ

使用 Slot 對 Component 傳入 HTML

Sam Xiao's Avatar 2024-02-21

對於 JavaScript 的資料,我們可透過 Prop 傳進 Component;但若要將 HTML 傳進 Component,則要使用 Slot。

Version

Vue 3.4

Slot

simple001

App.vue

<template>
  <MyCounter :initialCount="count">
    <span class="hello-count">Hello Count:</span>
  </MyCounter>
</template>

<script setup>
import { ref } from 'vue'
import MyCounter from '@/components/MyCounter.vue'

let count = ref(0)
</script>

<style scoped>
.hello-count {
  color: brown;
  font-weight: 700;
}
</style>

Line 2

<MyCounter :initialCount="count">
  <span class="hello-count">Hello Count:</span>
</MyCounter>
  • <MyCounter></MyCounter> 部分可夾 HTML 傳進 component,因此可使用 CSS 加以客製化

Line 15

.hello-count {
  color: brown;
  font-weight: 700;
}
  • 在 component 外部可自行使用 CSS 客製化

MyCounter

MyCounter.vue

<template>
  <div class="box">
    <button @click="onClick">+</button>
    <slot>Current count:</slot>
    {{ count }}
  </div>
</template>

<script setup>
import { ref } from 'vue'

let props = defineProps({ initialCount: Number })
let count = ref(props.initialCount)

let onClick = () => count.value++
</script>

<style scoped>
.box {
  border-style: solid;
  border-width: 2px;
  border-color: red;
  width: fit-content;
}
</style>

Line 3

<button @click="onClick">+</button>
<slot>Current count:</slot>
{{ count }}
  • <slot> 接收傳入 component 的 HTML
  • <slot></slot> 之間可提供預設顯示,當用戶端沒有提供 HTML 時則會以此顯示

Conclusion

  • 若有很多地方都使用該 component,但卻有 一小部分 的顯示不太一樣時,與其使用 prop 加上 v-ifv-else 控制,乾脆將該部分開放成 slot 由外層決定