基本知识点
🎯什么是自定义事件
自定义事件是子组件向父组件发送消息的机制,通常用于通知父组件发生了某些行为或状态变化。
📌 基本语法
子组件触发事件($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() |
。