【Vue】Vue3.0(二十二) v-model 在原始Dom元素、自定义输入组件中双向绑定的底层实现原理详解
上篇文章 【Vue】Vue3.0(二十一)Vue 3.0中 的$event使用示例
🏡作者主页:点击!
🤖Vue专栏:点击!
⏰️创作时间:2024年11月11日17点30分
文章目录
- 1. `v-model` 用于 HTML 标签时的底层原理
- 2. `v-model` 用于自定义组件时的底层原理
- 3. 自定义 `v-model` 修饰符的底层实现
- 4. 与响应式系统的结合
v-model
底层实现的详细解释:
1. v-model
用于 HTML 标签时的底层原理
当 v-model
用于普通的 HTML 输入标签(如 <input type="text">
)时,它实际上是一种语法糖,背后做了以下几件事:
- 数据绑定:
v-model
会将输入框的value
属性与 Vue 实例中的数据属性进行绑定。在上述Father.vue
中,v-model="username"
会将输入框的value
和username
建立双向数据绑定关系。这意味着当username
的值发生变化时,输入框的value
会自动更新,反之亦然。
- 事件监听:
- 同时,
v-model
会自动为输入框添加input
事件监听器。当用户在输入框中输入内容时,input
事件会被触发,然后事件处理函数会获取输入框的最新值,并将其更新到对应的 Vue 实例数据属性中。在底层,Vue 会自动处理这个更新过程,确保数据的一致性。
- 同时,
2. v-model
用于自定义组件时的底层原理
当 v-model
用于自定义组件(如 <AtguiguInput>
)时,它的实现方式略有不同,但遵循一定的约定:
modelValue
prop 和update:modelValue
事件:- 自定义组件需要通过名为
modelValue
的prop
来接收父组件传递的值,这类似于普通v-model
中的数据绑定部分。在AtguiguInput.vue
中,通过defineProps(['ming', 'mima'])
接收了父组件传递的ming
和mima
,这里的ming
和mima
就类似于modelValue
的作用,用于接收父组件的数据。 - 当子组件内部的数据发生变化时,需要通过触发名为
update:modelValue
的自定义事件来通知父组件更新数据。在AtguiguInput.vue
中,通过emit('update:ming', (<HTMLInputElement>$event.target).value)
和emit('update:mima', (<HTMLInputElement>$event.target).value)
实现了这一点,当输入框的input
事件触发时,会将最新的值通过相应的update
事件传递给父组件。
- 自定义组件需要通过名为
3. 自定义 v-model
修饰符的底层实现
在 Father.vue
中,使用了自定义的 v-model
修饰符 ming
和 mima
,这是对 v-model
功能的一种扩展:
- 自定义绑定和事件:
- 通过
v-model:ming="username"
和v-model:mima="password"
,Vue 会将username
和password
分别与子组件中的ming
和mima
进行绑定,并监听对应的update:ming
和update:mima
事件来更新数据。这种自定义修饰符的方式允许开发者根据具体需求灵活地定义数据绑定和事件更新的逻辑,使得v-model
在不同的场景下能够更精准地满足业务需求。
- 通过
4. 与响应式系统的结合
无论是用于 HTML 标签还是自定义组件,v-model
的底层实现都与 Vue 的响应式系统紧密结合:
- 数据更新的响应式传播:
- 当输入框的值发生变化并更新了 Vue 实例中的数据属性时,Vue 的响应式系统会检测到这个变化,并自动触发相关的 DOM 更新操作,确保所有依赖于该数据属性的视图部分都能得到及时更新。同样,当 Vue 实例中的数据属性在其他地方被修改时,绑定的输入框也会相应地更新显示,从而实现了数据和视图的双向同步更新,保持了整个应用的状态一致性。
综上所述,v-model
的底层实现通过数据绑定、事件监听、自定义事件触发以及与响应式系统的协作,为开发者提供了一种简洁而强大的双向数据绑定机制,无论是在普通的 HTML 表单元素还是自定义组件中,都能方便地实现数据与视图之间的交互和同步。
代码示例:
AtguiguInput.vue
<template><inputtype="text":value="ming"@input="emit('update:ming', (<HTMLInputElement>$event.target).value)"><br><inputtype="text":value="mima"@input="emit('update:mima', (<HTMLInputElement>$event.target).value)">
</template><script setup lang="ts" name="AtguiguInput">
defineProps(['ming', 'mima'])
const emit = defineEmits(['update:ming', 'update:mima'])
</script><style scoped>
input {border: 2px solid black;background-image: linear-gradient(45deg, red, yellow, green);height: 30px;font-size: 20px;color: white;
}
</style>
Father.vue
<template><div class="father"><h3>父组件</h3><h4>{{ username }}</h4><h4>{{ password }}</h4><!-- v-model用在html标签上 --><!-- <input type="text" v-model="username"> --><!-- <input type="text" :value="username" @input="username = (<HTMLInputElement>$event.target).value"> --><!-- v-model用在组件标签上 --><!-- <AtguiguInput v-model="username"/> --><!-- <AtguiguInput :modelValue="username" @update:modelValue="username = $event"/> --><!-- 修改modelValue --><AtguiguInputv-model:ming="username"v-model:mima="password"/></div>
</template><script setup lang="ts" name="Father">
import { ref } from "vue";
import AtguiguInput from './AtguiguInput.vue'
// 数据
let username = ref('zhansgan')
let password = ref('123456')
</script><style scoped>
.father {padding: 20px;background-color: rgb(165, 164, 164);border-radius: 10px;
}
</style>
详解:
1.
<!-- 使用v-model指令 -->
<input type="text" v-model="userName"><!-- v-model的本质是下面这行代码 -->
<input type="text" :value="userName" @input="userName =(<HTMLInputElement>$event.target).value"
>
-
组件标签上的
v-model
的本质::moldeValue
+update:modelValue
事件。<!-- 组件标签上使用v-model指令 --> <AtguiguInput v-model="userName"/><!-- 组件标签上v-model的本质 --> <AtguiguInput :modelValue="userName" @update:model-value="userName = $event"/>
AtguiguInput
组件中:<template><div class="box"><!--将接收的value值赋给input元素的value属性,目的是:为了呈现数据 --><!--给input元素绑定原生input事件,触发input事件时,进而触发update:model-value事件--><input type="text" :value="modelValue" @input="emit('update:model-value',$event.target.value)"></div> </template><script setup lang="ts" name="AtguiguInput">// 接收propsdefineProps(['modelValue'])// 声明事件const emit = defineEmits(['update:model-value']) </script>
-
也可以更换
value
,例如改成abc
<!-- 也可以更换value,例如改成abc--> <AtguiguInput v-model:abc="userName"/><!-- 上面代码的本质如下 --> <AtguiguInput :abc="userName" @update:abc="userName = $event"/>
AtguiguInput
组件中:<template><div class="box"><input type="text" :value="abc" @input="emit('update:abc',$event.target.value)"></div> </template><script setup lang="ts" name="AtguiguInput">// 接收propsdefineProps(['abc'])// 声明事件const emit = defineEmits(['update:abc']) </script>
-
如果
value
可以更换,那么就可以在组件标签上多次使用v-model
<AtguiguInput v-model:abc="userName" v-model:xyz="password"/>
相关文章:
【Vue】Vue3.0(二十二) v-model 在原始Dom元素、自定义输入组件中双向绑定的底层实现原理详解
上篇文章 【Vue】Vue3.0(二十一)Vue 3.0中 的$event使用示例 🏡作者主页:点击! 🤖Vue专栏:点击! ⏰️创作时间:2024年11月11日17点30分 文章目录 1. v-model 用于 HTML 标…...

史上最强大的 S3 API?介绍 Prompt API。
迄今为止,对象存储世界已由 PUT 和 GET 的 S3 API 概念定义。然而,我们现在生活的世界需要更多。鉴于 MinIO 的 S3 部署甚至比 Amazon 还多,因此我们不得不提出下一个出色的 S3 API。 这个新 API 就是 Prompt API,它很可能成为有…...

单片机设计智能翻译手势识别系统
目录 前言 一、本设计主要实现哪些很“开门”功能? 二、电路设计原理图 电路图采用Altium Designer进行设计: 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 在全球化的浪潮下,语言的多样性也为人们的交流带来了不小的挑战…...
「Mac玩转仓颉内测版12」PTA刷题篇3 - L1-003 个位数统计
本篇将继续讲解PTA平台上的题目 L1-003 个位数统计,通过对数字的处理与统计,掌握基础的字符串操作与数组计数功能,进一步提升Cangjie编程语言的实际应用能力。 关键词 PTA刷题数字统计数组操作字符串处理编程技巧 一、L1-003 个位数统计 题…...

飞书文档只读限制复制
飞书文档只读限制复制 场景描述解决方式插件安装测试 场景描述 当使用飞书时,可能会存在无对方文档编辑/管理权限,对方只给自己开放只读权限的时候,此时如果文档较重要,需要本地保存一份,但是又无法复制文档或直接屏蔽…...

【WPF】Prism学习(二)
Prism Commands 1.命令(Commanding) 1.1. ViewModel的作用: ViewModel不仅提供在视图中显示或编辑的数据,还可能定义一个或多个用户可以执行的动作或操作。这些用户可以通过用户界面(UI)执行的动作或操作…...

【鸿蒙开发】第二十一章 Location位置服务
目录 1 简介 1.1 Location Kit简介 1.2 运作机制 1.3 约束与限制 2 位置服务开发 2.1 申请位置权限开发指导 2.1.1 场景概述 2.2 获取设备的位置信息开发指导 2.2.1 场景概述 2.2.2 接口说明 2.2.3 开发步骤 2.3(逆)地理编码转化开发指导 2.…...

《目标检测》R-CNN网络基础(RCNN,Fast-RCNN)
文章目录 1.Overfeat模型2.RCNN网络2.1 算法流程2.1.1 候选区域的生成(了解,已经不再使用了)2.1.2 CNN网络提取特征2.1.3 目标分类(SVM)2.1.4 目标回归(线性回归修正坐标)2.1.5 预测过程 2.2 算…...

iOS中的定位实现(逆地理编码)及Info.plist位置权限详解
引言 在现代移动应用开发中,位置服务已经成为不可或缺的一部分。无论是地图导航、社交分享,还是基于位置的个性化推荐,位置数据都为用户提供了更加丰富和智能的体验。然而,随着用户隐私保护的不断加强,iOS对位置权限的…...

【从零开始的LeetCode-算法】3270. 求出数字答案
给你三个 正 整数 num1 ,num2 和 num3 。 数字 num1 ,num2 和 num3 的数字答案 key 是一个四位数,定义如下: 一开始,如果有数字 少于 四位数,给它补 前导 0 。答案 key 的第 i 个数位(1 < …...

Web认证机制 Cookie、Token、Session、JWT、OAuth2 解析
标题 一、Cookie二、Session三、Token四、JWTSSO(单点登录) 五、OAuth2如何设计权限系统区别总结 Cookie、Token、Session 和 JWT 都是在 Web 开发中常用的身份验证和授权技术,它们各有优缺点,适用于不同的场景。 Cookie 简单易用…...

Docker 基础命令介绍和常见报错解决
介绍一些 docker 可能用到的基础命令,并解决三个常见报错: 权限被拒绝(Permission Denied)无法连接到 Docker 仓库(Timeout Exceeded)磁盘空间不足(No Space Left on Device) 命令以…...

如何轻松导出所有 WordPress URL 为纯文本格式
作为一名多年的 WordPress 使用者,我深知管理一个网站的复杂性。从迁移网站、设置重定向到整理内容结构,每一步都需要精细处理。而拥有所有 URL 的清单,不仅能让这些工作变得更加简单,还能为后续的管理提供极大的便利。其实&#…...

【进程概念精讲】
Susan,在那命运月台前面,再上车,春天开始落叶.................................................................. 文章目录 前言 一、【认识进程】 1、【进程基本概念引入】 2、【进程的描述与组织——进程控制块(PCB)与进程…...

帽子矩阵--记录
帽子矩阵 H是一个重要的统计工具,用于评估数据点对模型拟合结果的影响。通过计算帽子矩阵的对角线元素(杠杆值),我们可以识别出高杠杆点,这些点对模型的影响较大,可能需要特别关注。...

MySQL深入:B+树的演化、索引和索引结构
提示:内容是读《MySQL技术内幕:InnoDB存储引擎》,笔记摘要 文章目录 二叉查找树平衡二叉树(AVL) B树(BTree)B树(BTree)InnoDB B树索引索引结构(InnoDB B树)B树存放的数据量 二叉查找树 在二叉查找树中,左子…...
axios 实现 无感刷新方案
实现思路 首次登录前端通过接口获取到两个 token;分别是 accessToken、refreshToken; accessToken:正常请求需要传递的 token ;refreshToken:当某个请求 401 ,就可以通过 refreshToken 获取到新的 accessToken 特殊场…...

Python 三种方式实现自动化任务
在这篇文章中,我们将介绍一些用Python实现机器人过程自动化的包。机器人流程自动化(Robotic process automation,简称RPA)是指将鼠标点击和键盘按压自动化的过程,即模拟人类用户的操作。RPA用于各种应用程序࿰…...
新型创业模式:退休创业。没有工资,不用投资,有时间就干,不强制做,赚钱按贡献分。
这种“退休创业”的创业模式具有独特的吸引力和灵活性,适合那些已退休但希望继续贡献社会价值、赚取额外收入且无需承担太多责任的群体。以下是一个详细的设计思路: 模式概述 目标人群:退休人员,具有一定技能或经验,但…...
Android 项目依赖库无法找到的解决方案
目录 错误信息解析 解决方案 1. 检查依赖版本 2. 检查 Maven 仓库配置 3. 强制刷新 Gradle 缓存 4. 检查网络连接 5. 手动下载依赖 总结 相关推荐 最近,我在编译一个 Android 老项目时遇到了一个问题,错误信息显示无法找到 com.gyf.immersionba…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...

软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...

ui框架-文件列表展示
ui框架-文件列表展示 介绍 UI框架的文件列表展示组件,可以展示文件夹,支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项,适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...

【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...

欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!
多连接 BLE 怎么设计服务不会乱?分层思维来救场! 作者按: 你是不是也遇到过 BLE 多连接时,调试现场像网吧“掉线风暴”? 温度传感器连上了,心率带丢了;一边 OTA 更新,一边通知卡壳。…...