iT邦幫忙

2025 iThome 鐵人賽

DAY 12
0
Modern Web

【網頁是什麼,能吃嗎】── 零基礎也能學會網頁製作系列 第 12

【Day 12】子元件的更多應用── Vue.js 入門篇

  • 分享至 

  • xImage
  •  

今天將是Vue.js入門的最後一篇文章,將會接續昨天的內容,繼續談論關於子元件的一些常見的應用與功能。那麼就讓我們直接開始今日的內容吧!

向父元件發送事件吧!

除了前一篇中所提及的給子元件傳送 props,我們亦可利用 emit 物件來反向給父元件發送事件(event),並由此方式來傳遞資訊。
在宣告時,我們使用defineEmits(),並傳入一陣列的字串,表示我們將會用到的事件名稱,接著再使用 emit() 來將指定的事件資訊傳出。有一點需要特別注意的是,若要接聽事件,將會需要使用**v-on**的指令。

下面這個小程式將會把 response 以及 name 事件的資訊 (分別為'hello from ' 與'child')傳回給父元件,而父元件則會把內容給顯示出來:

<!-- 檔案名稱:App.vue -->
<script setup>
import { ref } from 'vue'
import ChildComp from './ChildComp.vue'

const childMsg = ref('No msg yet from')
const childName = ref('Unknown')
</script>

<template>
  <ChildComp @response="(msg) => childMsg = msg"
             @name="(name) => childName = name"/>
  <p>{{ childMsg }}</p>
  <p>{{ childName }}</p>
</template>

<!-- 檔案名稱:ChildComp.vue -->
<script setup>
const emit = defineEmits(['response', 'name'])

emit('response', 'hello from ')
emit('name', 'child')
</script>

<template>
  <h2>Child component</h2>
</template>

利用 slot 來傳遞 template 的內容

與HTML的多數標籤相同,子元件也能夠以 opening/closing 標籤(<></>)的格式來撰寫,那麼我們可以在這標籤之間加入什麼內容呢?
這個位置名為 slot ,有長縫、投入口之意。這個slot其實與標題、段落(<h1>, <p>)等等所擁有的功能相似,除了能夠傳入其中撰寫的文字內容,也能使用兩個大括號,又稱做 mustache({{ }}),來將參數內容傳遞進去。
顯示內容將不會影響到子元件的template內容

<script setup>
import { ref } from 'vue'
import ChildComp from './ChildComp.vue'

const msg = ref('from parent')
</script>

<template>
  <ChildComp>The message is: {{ msg }}</ChildComp>
</template>

在子元件的 <template> 之中,也有著一個特別的標籤:<slot>,僅會在父元件呼叫時未利用slot傳入內容時,將其中的文字顯示出來,如下列範例所示:

<!-- 檔案名稱:App.vue -->
<script setup>
import { ref } from 'vue'
import ChildComp from './ChildComp.vue'

const msg = ref('from parent')
</script>

<template>
  <!-- 以下的slot為空白,與 <ChildComp /> 的效果相同 -->
  <ChildComp></ChildComp>
</template>

<!-- 檔案名稱:ChildComp.vue -->
<template>
  <slot>Fallback content</slot>
</template>

上一篇
【Day 11】把檔案拆開吧── Vue.js 入門篇
下一篇
【Day 13】來製作計算小遊戲!── Vue.js 實作篇
系列文
【網頁是什麼,能吃嗎】── 零基礎也能學會網頁製作14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言