2024-12-16 在 Vue 中,props 和 emits
在 Vue 中,props 和 emits
在 Vue 中,**props
和 emits
** 是用來實現父子組件之間的數據傳遞的兩種核心機制,主要用於建立單向數據流和事件驅動的交互。
父子組件的架構與數據傳遞流程
1. 父 -> 子:使用 props
父組件可以通過 props
將數據傳遞給子組件。
- 機制:父組件定義數據,子組件通過
props
接收。
- 特性:數據是 單向的(從父到子,子不能直接修改
props
)。
例子:
父組件:SplitBill.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <AddExpenseModal :members="members" /> </template>
<script> import AddExpenseModal from './AddExpenseModal.vue';
export default { components: { AddExpenseModal }, data() { return { members: [ { name: 'Alice', balance: 0 }, { name: 'Bob', balance: 0 }, ], }; }, }; </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
| <template> <div> <select v-model="selectedMember"> <option v-for="member in members" :key="member.name" :value="member.name"> {{ member.name }} </option> </select> </div> </template>
<script> export default { props: { members: { type: Array, required: true, }, }, data() { return { selectedMember: '', }; }, }; </script>
|
2. 子 -> 父:使用 emits
子組件可以通過 emits
將事件傳遞給父組件,父組件可以監聽這些事件來接收數據或觸發響應。
- 機制:子組件使用
$emit
發送事件,父組件使用 v-on
或 @
監聽事件。
- 特性:事件是 單向的(從子到父,子不能直接改變父組件的狀態)。
例子:
子組件:AddExpenseModal.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <template> <button @click="emitExpense">新增支出</button> </template>
<script> export default { emits: ['add-expense'], // 聲明事件名稱 methods: { emitExpense() { const expense = { name: 'Dinner', amount: 100 }; this.$emit('add-expense', expense); // 發送事件給父組件 }, }, }; </script>
|
父組件:SplitBill.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <AddExpenseModal @add-expense="handleExpense" /> </template>
<script> import AddExpenseModal from './AddExpenseModal.vue';
export default { components: { AddExpenseModal }, methods: { handleExpense(expense) { console.log('收到的支出:', expense); // 在此處接收子組件傳來的數據 }, }, }; </script>
|
props
與 emits
的關係與設計哲學
單向數據流:
- Vue 遵循「數據由上而下,事件由下而上」的設計。
- 父組件用
props
給子組件提供數據。
- 子組件用
emits
通知父組件狀態變化。
分工明確:
props
用於傳遞靜態或基於父組件動態變化的數據。
emits
用於傳遞交互事件或通知父組件數據更新。
解耦性高:
- 子組件不需要直接操作父組件的數據,只需要
emit
事件,保持子組件的獨立性和可重用性。
完整架構:父子數據交互示意圖
1 2 3 4 5 6 7 8
| 父組件 SplitBill.vue ↓ (數據傳遞) props:members ↓ 子組件 AddExpenseModal.vue ↑ emits:add-expense ↑ (事件回傳)
|
3. 在設計父子交互時的注意事項
命名一致性:
子組件的 props
和 emits
名稱要清晰、語義化,方便父組件理解。
避免過多的父子耦合:
如果父子組件的數據傳遞過於頻繁,可以考慮用 Vuex 或其他狀態管理工具。
**不能直接修改 props
**:
子組件如需修改數據,應通過 $emit
通知父組件更新,不能直接更改 props
。