v-model在自定义组件中需约定prop名与事件名:vue 2用value prop + input事件,vue 3用modelvalue prop + update:modelvalue事件,3.4+推荐definemodel()宏简化实现。

v-model 在自定义组件中不是开箱即用的魔法,而是需要明确约定“数据怎么进、变化怎么出”。核心就两点:父组件传值进来用什么 prop,子组件改完后发什么事件通知父组件更新。
Vue 2 的标准写法:value + input 事件
Vue 2 默认把 v-model 当作 :value 和 @input 的组合。所以子组件必须:
- 声明名为 value 的 prop,类型通常为 String / Number / Boolean 等
- 在内部触发 $emit('input', newValue),把新值抛给父组件
- 注意不要直接修改 props,应使用 data 或 computed + setter 做中间层
例如一个封装的输入框,<input :value="value"> 就满足了 v-model 的全部要求。
Vue 3 的推荐方式:modelValue + update:modelValue
Vue 3 把默认绑定名从 value 改为 modelValue,事件也对应改为 update:modelValue。这是为了支持多个 v-model(比如同时绑定 title 和 content)。
- props 中接收 modelValue,而非 value
- 使用 defineEmits(['update:modelValue']) 声明可触发事件
- 在输入、选择等时机调用 emit('update:modelValue', newValue)
这样父组件写 <custominput v-model="searchText"></custominput> 就能自动同步。
更简洁的 Vue 3.4+ 方案:defineModel()
从 Vue 3.4 开始,官方提供了 defineModel() 宏,大幅简化代码:
- 直接调用 const model = defineModel(),它返回一个 ref
- model.value 就是绑定的值,读写都自动同步到父组件
- 可直接把它绑定到原生 input 上:
<input v-model="model"> - 无需手动 emit,也不用定义 props 和 emits,底层已封装好
这是目前最轻量、最语义化的实现方式,适合大多数单值绑定场景。
进阶:自定义 v-model 名称和多 v-model
如果组件需要绑定多个字段,或想换掉默认的 modelValue 名称,可以用以下方式:
- 父组件用
v-model:title="pageTitle"和v-model:content="pageContent" - 子组件 props 接收 title 和 content
- 分别 emit update:title 和 update:content
- Vue 2 中还可通过 model: { prop: 'checked', event: 'change' } 配置全局绑定规则
这种灵活性让 v-model 能适配开关、评分、日期选择等复杂控件。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










