要让自定义组件支持双向绑定,需遵循 Vue 的 v-model 协议:Vue 2 中通过 value prop 和 input 事件实现;Vue 3 默认使用 modelValue prop 和 update:modelValue 事件,支持自定义绑定名及多 v-model;禁止直接修改 prop,应通过 $emit 通知父组件更新。

要让自定义组件支持双向绑定,核心是遵循 Vue 的 v-model 协议:组件内部通过 $emit('update:xxx') 通知父组件更新值,同时接收父组件传入的 xxx prop。Vue 3 中还支持更简洁的 v-model 语法糖,本质仍是 prop + 事件配合。
基础写法:v-model 默认绑定 value/ input
在 Vue 2 中,v-model 默认监听 value prop 并触发 input 事件:
- 组件声明
props: ['value'] - 内部表单元素绑定
:value="value" - 监听输入事件,如
@input="$emit('input', $event.target.value)" - 父组件即可用
<my-input v-model="msg"></my-input>实现双向同步
Vue 3 的 v-model 语法糖(推荐)
Vue 3 允许自定义 v-model 绑定的 prop 名和事件名,默认仍是 modelValue 和 update:modelValue:
- 组件接收
modelValueprop:props: ['modelValue'] - 绑定子元素:
:value="modelValue"或:checked="modelValue" - 触发更新:
@change="$emit('update:modelValue', $event.target.checked)" - 父组件写法不变:
<my-switch v-model="isActive"></my-switch>
支持多个 v-model(多属性绑定)
可通过命名 v-model 实现多个双向绑定:
- 组件定义两个 prop:
props: ['title', 'content'] - 分别触发:
$emit('update:title', newTitle)、$emit('update:content', newContent) - 父组件使用:
<my-editor v-model:title="doc.title" v-model:content="doc.content"></my-editor>
注意细节:避免直接修改 prop
切勿在组件内直接赋值 this.modelValue = newValue,这会触发 Vue 警告。必须通过 $emit 通知父组件修改,由父组件响应式更新再传回新值。如果需要本地缓存或转换,可用计算属性的 set + get 封装:
computed 包裹 modelValue,在 set 中 emit,在 get 中返回原值或处理后值。

















