組件開發:自訂事件
## Vue 中自定義事件的觀念
Vue 組件通常遵循「**資料向下傳遞,事件向上通知**」的設計:
- **父組件 → 子組件**:透過 `props` 傳遞資料
- **子組件 → 父組件**:透過自定義事件 `emit` 通知父組件
- 父組件在子組件上使用 `@事件名稱` 監聽事件
基本流程如下:
```text
父組件傳入 props
↓
子組件
↓
子組件 emit 自定義事件
↓
父組件接收並處理
```
自定義事件適合用來通知父組件:
- 按鈕被點擊
- 表單送出
- 資料被修改
- 子組件中的某項操作已完成
> 自定義事件名稱通常使用 kebab-case,例如 `@add-count`。
---
# 範例:計數器組件
此範例由兩個組件組成:
1. `App.vue`:父組件,管理目前的數字
2. `CounterButton.vue`:子組件,顯示按鈕並發出自定義事件
---
## 1. `CounterButton.vue`
```vue
<script setup>
const emit = defineEmits(['add-count'])
function handleClick() {
emit('add-count', 1)
}
</script>
<template>
<button @click="handleClick">
增加 1
</button>
</template>
<style scoped>
button {
padding: 8px 16px;
font-size: 16px;
cursor: pointer;
}
</style>
```
### 說明
```js
const emit = defineEmits(['add-count'])
```
宣告子組件可以發出名為 `add-count` 的自定義事件。
```js
emit('add-count', 1)
```
發出事件時,也可以附帶資料。此處傳送數字 `1`。
---
## 2. `App.vue`
```vue
<script setup>
import { ref } from 'vue'
import CounterButton from './components/CounterButton.vue'
const count = ref(0)
function addCount(amount) {
count.value += amount
}
</script>
<template>
<main class="page">
<h1>Vue 自定義事件範例</h1>
<p>目前數字:{{ count }}</p>
<!-- 監聽子組件發出的 add-count 事件 -->
<CounterButton @add-count="addCount" />
</main>
</template>
<style scoped>
.page {
max-width: 500px;
margin: 80px auto;
text-align: center;
font-family: Arial, sans-serif;
}
p {
font-size: 24px;
margin: 24px 0;
}
</style>
```
---
## 執行流程
當使用者點擊 `CounterButton`:
```js
emit('add-count', 1)
```
子組件會發出 `add-count` 事件,並傳遞 `1` 給父組件。
父組件透過以下方式監聽:
```vue
<CounterButton @add-count="addCount" />
```
收到事件後,執行:
```js
function addCount(amount) {
count.value += amount
}
```
因此畫面上的數字就會增加。
---
## 重點整理
```vue
<!-- 父組件監聽子組件事件 -->
<ChildComponent @custom-event="handleEvent" />
```
```js
// 子組件發出事件
emit('custom-event', data)
```
自定義事件的核心概念就是:
> 子組件不直接修改父組件資料,而是發出事件通知父組件,由父組件決定如何處理。
相關學習地圖、教學課程
F2E 網站前端工程