Vue 2 Options API 中子传父通信通过 this.$emit 触发事件、v-on 监听实现;子组件调用 this.$emit('事件名', 数据) 抛出事件,父组件用 @事件名="处理函数" 接收,推荐传对象以保证结构清晰。

在 Vue 2 的 Options API 中,子组件通过 this.$emit 触发自定义事件,父组件用 v-on(或简写 @)监听,从而实现子传父数据。这是最基础、最常用的通信方式。
子组件:用 this.$emit 发送事件
在子组件的方法中调用 this.$emit('事件名', 数据),即可向父组件抛出事件和携带的参数:
- 事件名建议用短横线格式(如 update-name),避免和原生事件冲突
- 第二个及后续参数都会作为事件的载荷(payload)传递给父组件
- 不能在
data、computed或生命周期钩子中直接 emit(除非明确在方法或响应式回调里调用)
示例(子组件):
export default {
methods: {
handleClick() {
this.$emit('submit-form', { name: '张三', age: 25 })
this.$emit('close-dialog')
}
}
}
父组件:用 v-on 监听并接收数据
父组件在使用子组件标签时,用 v-on:事件名="处理函数" 绑定监听器。事件回调函数的第一个参数默认就是子组件 emit 传来的第一个数据:
- 可以写成内联语句:
@submit-form="onSubmit" - 也可以直接写表达式:
@submit-form="name = $event.name"(不推荐复杂逻辑) - 若子组件 emit 多个参数,父组件函数可接收多个形参,但更推荐只传一个对象,结构清晰
示例(父组件模板):
<child-component @submit-form="handleFormSubmit" @close-dialog="isDialogOpen = false" />
对应 JS 部分:
methods: {
handleFormSubmit(payload) {
console.log(payload.name) // '张三'
console.log(payload.age) // 25
}
}
注意:不要忘记命名规范与触发时机
Vue 官方建议避免在子组件中直接修改父组件传入的 prop,而是通过 emit 通知父组件“我需要你改”。常见场景包括:
- 表单输入后触发
@input或自定义@update:value(配合.sync修饰符) - 按钮点击后提交数据、关闭弹窗、切换状态等
- 子组件内部状态变化(如分页页码、筛选条件)需同步到父组件
如果事件未被监听,$emit 不会报错,但数据无法到达父组件——建议开发时检查控制台是否出现 Failed to resolve directive: on 类似提示(通常是绑定写错了)。
补充:v-model 在 Options API 中的原理
Vue 2 的 v-model 本质就是语法糖:<child-component v-model="value" /> 等价于:<child-component :value="value" @input="val => value = val" />
因此,只要子组件正确 emit input 事件,并接收 value prop,就能支持 v-model。如需自定义事件名(如 change),可用 .model 修饰符或手动绑定。


















