v-model 实现父子组件表单双向同步,本质是基于 :modelValue 和 @update:modelValue 协议,在保持单向数据流前提下模拟原生表单行为;支持多字段参数化绑定(如 v-model:name)及修饰符扩展(如 v-model.trim)。

用 v-model 实现父子组件表单输入值的实时双向同步,是最自然、最符合 Vue 设计意图的方式。它本质不是“魔法”,而是基于 :modelValue 和 @update:modelValue 这组约定形成的通信协议,既保持单向数据流原则,又让交互看起来像原生表单一样顺滑。
子组件接收并响应父数据
子组件需声明接收 modelValue prop,并在内部 input 变化时触发更新事件:
- 使用
defineProps(['modelValue'])或更推荐的类型安全写法:defineProps({ modelValue: { type: [String, Number], default: '' } }) - 在 input 的
@input或@change中调用emit('update:modelValue', $event.target.value)(Vue 3 组合式 API) - 注意:不要直接修改 props,而是通过事件通知父组件——这是单向数据流的核心约束
父组件绑定 v-model 即完成双向联动
父组件只需像操作普通表单一样使用 v-model,无需额外监听或赋值逻辑:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
<CustomInput v-model="formData.name" />- 背后等价于:
<CustomInput :modelValue="formData.name" @update:modelValue="val => formData.name = val" /> - 只要父组件的
formData.name是响应式(如用ref或reactive定义),输入即实时更新,父组件数据变化也会自动同步到子组件显示
支持多字段时用参数化 v-model
一个组件要同时管理多个字段(如姓名、邮箱、状态),可避免把所有数据打包成对象传入:
立即学习“前端免费学习笔记(深入)”;
- 父组件写法:
<UserProfile v-model:name="user.name" v-model:email="user.email" v-model:active="user.active" /> - 子组件对应接收:
defineProps({ name: String, email: String, active: Boolean }) - 子组件触发事件:
emit('update:name', newValue)、emit('update:email', newValue)等 - 每个 v-model 参数都独立走一套 “prop + update:xxx” 流程,互不干扰,逻辑更清晰
补充:v-model 修饰符可注入业务逻辑
比如需要输入时自动 trim 或转小写,不必在父组件反复处理:
- 子组件中判断修饰符:
if (props.trim) newValue = newValue.trim() - 父组件启用:
<CustomInput v-model.trim="username" /> - 修饰符会作为 prop 透传给子组件(
defineProps({ trim: Boolean })),让格式化逻辑封装在组件内部

















