2024-12-19 父子組件之間通過事件傳遞資料的方式。
父子組件之間通過事件傳遞資料的方式。讓我們整理和補充這個配對關係。
父子組件事件傳遞的完整架構
1. 父組件模板:
2. 子組件腳本:
- 子組件使用
this.$emit('事件名稱', 資料)
觸發事件,並將資料傳遞給父組件。
- 在
emits
中聲明子組件能觸發的事件名稱(Vue 3 新增的功能,避免意外事件發生)。
語法:
1 2 3 4 5 6 7 8
| export default { emits: ['事件名稱'], methods: { someMethod() { this.$emit('事件名稱', 傳遞的資料); }, }, };
|
範例實作:
父組件:SplitBill.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <template> <div> <h2>成員清單</h2> <ul> <li v-for="(member, index) in groupMembers" :key="index"> {{ member.name }} - {{ member.balance }} </li> </ul> <!-- 父組件監聽子組件的 add-expense 事件,並呼叫父組件的 handleAddExpense 方法 --> <AddExpenseModal :members="groupMembers" @add-expense="handleAddExpense" /> </div> </template>
<script> import AddExpenseModal from './AddExpenseModal.vue';
export default { components: { AddExpenseModal }, data() { return { groupMembers: [ { name: 'Alice', balance: 0 }, { name: 'Bob', balance: 0 }, ], }; }, methods: { handleAddExpense(expenseData) { // 處理子組件傳來的資料 console.log('收到的支出資料:', expenseData); alert(`${expenseData.name} 支出 ${expenseData.amount}`); }, }, }; </script>
|
子組件:AddExpenseModal.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| <template> <div> <h3>新增支出</h3> <input v-model="expenseAmount" type="number" placeholder="輸入支出金額" /> <select v-model="selectedMember"> <option v-for="(member, index) in members" :key="index" :value="member.name"> {{ member.name }} </option> </select> <button @click="addExpense">確定</button> </div> </template>
<script> export default { props: { members: { type: Array, required: true, }, }, emits: ['add-expense'], // 聲明子組件會觸發的自定義事件 data() { return { expenseAmount: 0, // 綁定使用者輸入的支出金額 selectedMember: '', // 綁定選擇的成員名稱 }; }, methods: { addExpense() { if (!this.selectedMember || this.expenseAmount <= 0) { alert('請選擇成員並輸入有效金額'); return; } // 觸發自定義事件,並傳遞資料給父組件 this.$emit('add-expense', { name: this.selectedMember, amount: this.expenseAmount, });
// 清空輸入框 this.expenseAmount = 0; this.selectedMember = ''; }, }, }; </script>
|
流程解釋:
父組件監聽事件:
- 父組件在
AddExpenseModal
的標籤中,使用 @add-expense="handleAddExpense"
綁定子組件事件 add-expense
。
- 當子組件觸發
add-expense
時,父組件會執行 handleAddExpense
方法。
子組件觸發事件:
- 子組件在需要時(例如按下「確定」按鈕後),通過
this.$emit('add-expense', 資料)
觸發 add-expense
事件,並傳遞資料給父組件。
資料傳遞:
- 子組件內部
this.$emit('add-expense', {name: ..., amount: ...})
傳出資料。
- 父組件的
handleAddExpense
方法接收到這個資料,並進行後續處理。
補充:props 和 emits 的搭配
- **
props
**:用於從父組件傳資料給子組件(父 → 子)。
- **
emits
**:用於子組件將事件和資料傳回給父組件(子 → 父)。
這樣,父子組件之間的互動就可以完成雙向的資料流通。