v-model在自定义组件中需显式接收modelValue prop并触发update:modelValue事件,Vue 3.4+推荐用defineModel()简化多字段绑定与修饰符处理。

v-model 在自定义组件上实现双向绑定通信,核心是遵循“接收 prop + 触发更新事件”的显式契约,不是自动魔法。Vue 3 默认使用 modelValue 作为输入值的 prop 名,用 update:modelValue 事件通知父组件更新。
基础写法:支持默认 v-model
子组件需明确声明接收和响应:
- 用 defineProps({ modelValue: [String, Number, Boolean] }) 接收值
- 用 defineEmits(['update:modelValue']) 声明可触发事件
- 模板中绑定原生元素:<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
- 父组件直接写 <MyInput v-model="userName"></MyInput>,等价于手动传 prop + 监听事件
多字段或自定义名绑定(如 v-model:title)
当一个组件需要同步多个状态时,可扩展 v-model 的语义:
- 父组件写 <PostEditor v-model:title="post.title" v-model:content="post.content"></PostEditor>
- 子组件需分别声明 title 和 content prop,并 emit update:title 和 update:content
- Vue 3.4+ 推荐用 const title = defineModel('title'),模板中直接 v-model="title",自动处理读写与事件
处理 .number、.trim 等修饰符
v-model 修饰符不会自动生效,需组件内主动识别并处理:
- 在 props 中接收 modelModifiers: { default: () => ({}) }
- 判断 modelModifiers.number 为 true 时,emit 前转数字:parseFloat($event.target.value)
- 判断 modelModifiers.trim 为 true 时,emit 前调用 .trim()
- 使用 defineModel() 可自动支持常见修饰符,无需手动判断
兼容 Vue 2 的写法(仅限过渡场景)
若需兼容旧项目或特定组件类型(如 checkbox),可用 model 选项自定义绑定行为:
- 在组件选项中配置 model: { prop: 'checked', event: 'change' }
- props 声明 checked,事件中 $emit('change', newValue)
- 此时 v-model="isChecked" 就会作用于 checked prop 并监听 change 事件


















