【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…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...