vue 3 中 props 不支持双向绑定,需通过 props 接收 + emit 触发 update:xxx 事件模拟;推荐用 v-model:xxx 或 vue 3.4+ 的 definemodel();手动 watch 适用于复杂场景,但须避免直接修改 props。

Vue 3 中 Props 本身不直接支持双向绑定——它严格遵循单向数据流原则,即父传子、不可逆改。所谓“双向绑定”,其实是通过 props 接收 + emit 触发更新事件 的组合逻辑模拟出来的响应式同步效果。核心不是让 props 可写,而是让子组件能“请求父组件更新”,并自动同步回子组件的本地状态。
用 v-model:xxx 实现标准双向绑定
这是最推荐、最简洁的方式,Vue 3 已将 v-model 语法糖标准化为 prop 名 + update:事件 的约定:
- 父组件使用
v-model:fieldName="parentData",等价于同时传递:fieldName="parentData"和监听@update:fieldName - 子组件声明
props: { fieldName: String },并在需要更新时调用emit('update:fieldName', newValue) - 子组件内部通常用
ref(props.fieldName)或computed构建可读写的本地响应式变量,避免直接修改 props
用 defineModel() 简化写法(Vue 3.4+ 推荐)
Vue 3.2 起引入 defineModel(),3.4 后全面优化,它把上述模板逻辑封装成一行声明:
- 子组件中直接写
const model = defineModel(),得到一个 ref,其.value自动与父组件v-model绑定的值同步 - 修改
model.value会自动触发update:modelValue;父组件更新源数据,model.value也实时响应 - 支持多字段:如
v-model:count="c"对应const count = defineModel('count')
手动 watch props 实现受控同步(适合复杂场景)
当子组件需处理异步初始值、校验拦截或保持本地编辑态时,可主动监听 props 变化:
- 用
watch(() => props.modelValue, (val) => localVal.value = val, { immediate: true })确保初始化同步 - 在输入/选择等操作中,先做校验,再决定是否
emit('update:modelValue', newVal) - 注意避免无限循环:不要在 watch 回调里直接改
props.xxx,只更新本地 ref 或 computed setter
关键注意事项
无论哪种方式,都要牢记:
- Props 是只读的——直接赋值会报错或静默失败
- 引用类型 props(如对象、数组)若需本地修改,必须用结构赋值或深拷贝创建副本
- 默认 prop 名是
modelValue,但可自定义;对应事件名必须是update:xxx,不能拼错 - 父子组件数据一致性依赖于 emit 的及时性,延迟 emit 或漏发会导致视图脱节
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










