《v-model原理 》以及 《自定义组件实现v-model》

一、v-model 的实现机制解析

1. 表单元素中的实现机制

v-model 的实现本质是通过 双向数据绑定语法糖 ,将 v-bind:valuev-on:input 组合封装。

html 复制代码
<input v-model="message">

等价于以下代码

html 复制代码
<input 
  :value="message" 
  @input="message = $event.target.value"
>

数据 → 视图 :通过 v-bind:value 将数据绑定到表单的 value 属性(或 checkedselected 等属性)

视图 → 数据 :监听 input 事件(或其他适配事件),通过事件对象 $event.target.value 更新数据


二、 自定义组件中的实现机制

在自定义组件中,v-model 通过 props + 事件 的组合实现父子组件双向通信,且支持 多数据绑定(Vue 3 特性)。

1、父组件实现

通过 v-model:test_data 指定自定义 prop 名称,将父组件 data 变量绑定到子组件的 test_data prop

html 复制代码
<template> 
  <ChildComponent v-model:test_data="data" /> 
 </template> 
 
<script> 
  import ChildComponent from "./ChildComponent" 
  const data = ref('aaa') 
</script> 
   
<style> </style>

2、子组件实现

props 接收 :通过 test_data prop 接收父组件数据

事件触发 :通过 emit('update:test_data') 事件反向更新父组件数据

双向同步 :子组件修改数据后,父组件的 data 变量会自动更新

javascript 复制代码
// 接收父组件传递的 prop
const props = defineProps({
  test_data: {
    type: String,
    required: true
  }
});

// 定义事件发射器
const emit = defineEmits(['update:test_data']);

// 数据更新逻辑
const handleChange = (str) => {
  emit('update:test_data', str); // 触发自定义事件,告知父组件更新数据
}

三、 为什么定义emit事件为 update:xxx

update:xxx 是 Vue 的​​双向绑定约定语法​ ​,当父组件通过 v-model:test_data 绑定时:

  1. ​自动映射​​:

    父组件的 v-model:test_data="data" 会被编译为:

    html 复制代码
    <ChildComponent 
      :test_data="data" 
      @update:test_data="data = $event"
    />

    子组件的 emit('update:test_data', newValue) 会触发父组件的数据更新。

四、v-model可以绑定多个

v-model支持 ​​多字段扩展​​:

允许一个组件同时绑定多个独立字段(如 v-model:firstNamev-model:lastName

html 复制代码
<CustomInput 
  v-model:first-name="firstName" 
  v-model:last-name="lastName"
/>

(PS): 同时绑定多个独立数据流,需在子组件分别定义对应的 props 和 emit 事件

五、 注意事项

  1. 避免直接修改 prop
    子组件应通过事件触发更新,而非直接修改父组件传递的 prop
  2. 复杂数据结构处理
    对象类型数据需使用 v-model 的深层绑定特性(Vue 3 新增)
  3. 性能敏感场景
    高频输入场景建议使用 .lazy 修饰符减少更新频率
相关推荐
Tigger3 分钟前
用 Vue 3 做了一套年会抽奖工具,顺便踩了些坑
前端·javascript·vue.js
天天扭码8 分钟前
一文搞懂——React 19到底更新了什么
前端·react.js·前端框架
weixin_4624462313 分钟前
【原创】使用langchain与MCP 与 Chrome DevTools 打造可调用浏览器工具的 Chat Agent
前端·langchain·chrome devtools
OpenTiny社区22 分钟前
OpenTiny 2025年度贡献者榜单正式公布~
前端·javascript·vue.js
OEC小胖胖26 分钟前
08|Commit 阶段:副作用如何被组织、执行与约束
前端·react.js·前端框架·react·开源库
biubiubiu070630 分钟前
Vue脚手架创建项目记录
javascript·vue.js·ecmascript
奋斗的小青年!!33 分钟前
Flutter跨平台开发OpenHarmony应用:个人中心实现
开发语言·前端·flutter·harmonyos·鸿蒙
kkce40 分钟前
域名CDN检测意义
服务器·前端·网络
北辰alk40 分钟前
Vue 表单修饰符 .lazy:性能优化的秘密武器
vue.js
北辰alk41 分钟前
`active-class`:Vue Router 链接组件的激活状态管理
vue.js