Skip to content

Vue 3 實戰:掌握 Emit 事件機制實現子傳父元件通訊

在 Vue 的單向數據流架構中,父元件透過 props 向下傳遞資料,而子元件若要與父元件溝通,則必須透過 emit(事件)。這是一種「由下而上」的通知機制,讓子元件能在特定行為發生時,告知父層進行相應處理。

快速觸發事件(Template 內直接使用)

如果您只需要在按鈕點擊時進行簡單的通知,可以在元件的樣版中直接使用內建 $emit 方法向上(父)層通知。

下(子)層發出通知

html
<input type="button" @click="$emit('someEvent')" value="通知上(父)層" />

上(父)層監聽事件

父元件可以像監聽原生 DOM 事件一樣,使用 @v-on)來接收子元件的訊號:

html
<Counter @some-event="counter++" />
<Counter @some-event="() => counter++" />
<Counter @some-event="updateCounter" />
js
function updateCounter() {
  counter.value++;
}

小提醒

若有需要向父層傳遞特殊資料,可用參數的方式傳遞。如: $emit('someEvent', 100);

專業提醒

雖然在樣版中可以寫成 someEvent,但在 Vue 慣例中,事件名稱建議在 HTML 監聽時使用 Kebab-case(如 @some-event),而在 JavaScript 中發送時使用 CamelCase

正式宣告觸發事件(使用 defineEmits

在更複雜的邏輯中,我們通常會在 <script setup> 內使用 defineEmits 來明確宣告該元件會發出的事件。這不僅讓程式碼更具閱讀性,也能讓 IDE 提供更好的補全建議。

js
// 宣告該元件擁有的自定義事件
const emit = defineEmits(["someEvent"]);

function clickHandler() {
  // 執行一些邏輯處理後,再發出事件
  console.log("準備通知父層...");
  emit("someEvent");
}

進階應用:事件攜帶參數(傳遞資料)

有時候我們不只是要發出「通知」,還需要把子元件內部的資料「傳給」父層。這時可以將資料作為 $emitemit 的第二個參數傳出。

子元件傳遞數值

js
// 在 script setup 中傳遞
emit("updateCount", 100);

// 或在 template 中傳遞
// <button @click="$emit('updateCount', 100)">傳送 100</button>

父元件接收參數

父元件的方法會自動接收到這個傳出的值:

js
function handleUpdate(payload) {
  console.log("接收到來自子層的資料:", payload); // 輸出:100
  counter.value = payload;
}

總結:元件溝通的核心原則

  • props 往下傳:資料從父層傳給子層。
  • emits 往上傳:事件從子層通知父層。

透過這套「資料下行、事件上行」的機制,我們能確保元件之間的耦合度降低,讓應用的狀態管理變得更加可預測且易於維護。