基本知識點
🎯什么是自定義事件
自定義事件是子組件向父組件發送消息的機制,通常用于通知父組件發生了某些行為或狀態變化。
📌 基本語法
子組件觸發事件($emit)
this.$emit('事件名', 參數);
或在
const emit = defineEmits([‘事件名’]);
emit(‘事件名’, 參數);
父組件監聽事件
<Child @事件名="父組件方法" />
??完整例子(Vue 2 & 3 通用)
子組件 Child.vue<template><button @click="handleClick">點我</button>
</template><script>
export default {methods: {handleClick() {this.$emit('my-event', '來自子組件的數據');}}
}
</script>父組件 Parent.vue<template><Child @my-event="onChildEvent" />
</template><script>
import Child from './Child.vue';export default {components: { Child },methods: {onChildEvent(data) {console.log('收到子組件數據:', data);}}
}
</script>
🚀 Vue 3
子組件
<template><button @click="emitEvent">點我</button>
</template><script setup>
const emit = defineEmits(['custom-event'])function emitEvent() {emit('custom-event', 'Hello from child')
}
</script>
進階使用
🔁 自定義 v-model
Vue 2 中
v-model 默認綁定 value 和 input,可以通過修改 model 配置自定義:
export default {model: {prop: 'checked',event: 'change'},props: ['checked'],methods: {toggle() {this.$emit('change', !this.checked)}}
}
使用方式:
<MyCheckbox v-model="isChecked" />
Vue 3 中(支持多個 v-model)
<!-- 子組件 -->
<script setup>
defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])function updateValue(val) {emit('update:modelValue', val)
}
</script>
使用方式:
<MyInput v-model="inputValue" />
多個綁定:
<MyInput v-model:title="title" v-model:content="content" />
🪞 事件透傳(事件代理)
有時需要把子組件的事件直接傳遞給更高層的父組件。
方法一:手動轉發
<!-- 中間組件 -->
<Child @update="emit('update', $event)" />
方法二:使用 v-on=“$attrs”(Vue 3)
<Child v-on="$attrs" />
?? 需要在子組件中加上 inheritAttrs: false(如果不希望自動綁定到根元素)。
🔧 事件修飾符(只適用于 DOM 事件)
事件修飾符如 .stop、.prevent 僅適用于 DOM 事件,不作用于 $emit 的自定義事件。
例如:
<!-- 這是 DOM 事件,不是組件事件 -->
<button @click.stop="doSomething">點我</button>
對于組件事件,比如:
<MyDialog @close="onClose" />
修飾符不會生效。你必須在組件內部自己調用 event.stopPropagation() 來阻止冒泡。
📡 多層組件通信的事件管理
場景:孫組件觸發事件,祖組件監聽。
? 不推薦:跨多層 $emit 傳遞
中間組件每層都要轉發事件,代碼冗余。
? 推薦方式:事件總線 / 狀態管理
? 小項目:使用 mitt 事件總線
? 大項目:用 Pinia / Vuex 等狀態管理工具
// event-bus.js
import mitt from 'mitt'
export const bus = mitt()// 子組件觸發
bus.emit('custom-event', data)// 祖組件監聽
onMounted(() => {bus.on('custom-event', handler)
})
🧩 使用 emits 選項做類型校驗(Vue 3)
defineEmits<{(e: 'submit', formData: Record<string, any>): void(e: 'cancel'): void
}>()
這不僅提供類型提示,也幫助 IDE 檢查事件是否被正確觸發。
🔚 總結:進階重點
功能 | 推薦方式 |
---|---|
自定義 v-model | update:modelValue |
事件透傳 | $attrs 或中轉 emit |
多層通信 | mitt / 狀態管理 |
類型提示 | defineEmits 泛型形式 |
事件阻止冒泡 | 在組件內部使用原生 stopPropagation() |
。