《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 修饰符减少更新频率
相关推荐
jeffwang22 分钟前
我做了个让 AI 看屏幕跑测试的工具,因为 Playwright 测不了我的 Flutter Web
前端
HSunR1 小时前
dify 搭建ai作业批改流
开发语言·前端·javascript
代码不加糖1 小时前
2026 跨境电商独立站实战:从 0 到 1 搭建高转化 SaaS 商城(附源码)
开发语言·前端·javascript
亲亲小宝宝鸭1 小时前
拖一拖控件,拖出个问卷(低代码平台)
前端·低代码
江南十四行1 小时前
ReAct Agent 基本理论与项目实战(一)
前端·react.js·前端框架
We་ct2 小时前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·leetcode·typescript·动态规划
小呆呆6662 小时前
Codex 穷鬼大救星
前端·人工智能·后端
当时只道寻常3 小时前
Vue3 + IntersectionObserver 实现高性能图片懒加载
前端
sakiko_3 小时前
UIKit学习笔记3-布局、滚动视图、隐藏或显示视图
前端·笔记·学习·objective-c·swift·uikit
有一个好名字4 小时前
Agent Loop —— 一切从那个 while 循环开始
前端·javascript·chrome