子组件通过 emit('update:xxx', value) 通知父组件更新,父组件用 @update:xxx="val => xxx = val" 或 v-model="xxx" 接收;须声明 defineEmits(['update:xxx']),避免拼写错误、括号调用及 ref/.value 遗漏。

子组件不能直接修改父组件的 props,但可以通过 emits 主动通知父组件“该更新什么”,由父组件执行赋值操作——这是 Vue 实现子改父状态的标准且唯一合规方式。
明确事件名规范:用 update:xxx 格式
Vue 官方推荐使用 update:xxx 命名约定(如 update:count、update:visible),这样能与 v-model 机制自动对齐,也更语义化:
- 子组件中声明:
const emit = defineEmits(['update:count']) - 触发时写:
emit('update:count', newValue) - 父组件监听:
@update:count="count = $event"或@update:count="handleUpdate"
父组件接收并更新变量
父组件监听事件后,直接修改自己的响应式数据即可。不需要额外逻辑,关键在绑定方式:
- 简写形式(推荐):
<child></child> - 函数形式(适合需处理逻辑):
<child></child>,然后定义function onCountUpdate(val) { count.value = val } - 若用 ref,注意赋值用
.value;若用 reactive,直接点属性赋值
配合 v-model 简化双向绑定
当子组件只同步单个值时,可直接用 v-model,它本质就是语法糖:
立即学习“前端免费学习笔记(深入)”;
- 子组件:
emit('update:modelValue', newValue) - 父组件:
<child v-model="count"></child>→ 自动展开为<child :model-value="count"></child> - 如需自定义 prop 名和事件名,可用
v-model:xxx="value",对应update:xxx事件
注意避免常见错误
这类通信失败多数源于细节疏忽:
- 子组件未用
defineEmits声明事件名,或拼写不一致(比如写了updata:count) - 父组件监听时用了括号:
@update:count="onUpdate()"→ 错误,应写@update:count="onUpdate"(不加括号,传函数引用) - 子组件在 setup 中调用
emit时,第一个参数不是字符串字面量,而是变量或表达式,导致运行时校验失败 - 父组件用
ref接收值但忘了加.value,或用reactive却误写成state.count = $event(正确是state.count = $event,无需解构)


















