《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 修饰符减少更新频率
相关推荐
Avan_菜菜1 天前
AI 能写代码了,为什么我反而开始要求它先写文档?
前端·github·ai编程
爱勇宝1 天前
鸿蒙生态的下半场:开发者不只要能开发,还要能赚钱
android·前端·程序员
IT_陈寒1 天前
SpringBoot这个自动配置坑我跳了三次
前端·人工智能·后端
kyriewen1 天前
我用 AI 一周写完了整个项目,上线第一天就崩了——这是我踩过最贵的 5 个坑
前端·javascript·ai编程
牧艺1 天前
从零到协同:构建类飞书在线文档系统的五个技术重难点
前端·人工智能
红尘散仙1 天前
想写一个像样的终端 App?试试把 React 的开发体验搬进 Rust TUI
前端·rust
袋鼠云数栈UED团队1 天前
一套 Spec-First 的 AI 编程工作流
前端·人工智能
袋鼠云数栈前端1 天前
一套 Spec-First 的 AI 编程工作流
前端·ai+
angerdream1 天前
Android手把手编写儿童手机远程监控App之vue3 路由守卫
前端
不服老的小黑哥1 天前
AI规范驱动编程-harness工程项目实战
前端