热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

vmodel双向绑定原理_【Vue原理】VModel白话版

专注Vue源码分享,为了方便大家理解,分为了白话版和源码版,白话版可以轻松理解工作原理和设计思想,源码版可以更清楚内部操作和
18e7b69089558ec4762ce5ec581c1c78.png
专注 Vue 源码分享,为了方便大家理解,分为了白话版和 源码版,白话版可以轻松理解工作原理和设计思想,源码版可以更清楚内部操作和 Vue的美,喜欢我就关注我的公众号,公众号的文章,排版更好看

如果你觉得排版难看,请点击下面链接 或者 关注公众号

【Vue原理】VModel - 白话版​mp.weixin.qq.com
1eebceec35f9882e917449c4c61de94a.png

说到 Vue,感觉第一印象就是双向绑定,所以v-model键值是Vue印象的半壁江山啊,这么重要的东西,你好歹要知道是怎么实现的吧

我们今天就来讲解双向绑定的工作原理,你应该知道,双向绑定就是通过绑定 dom 事件来实现的,可是,怎么绑定的事件,绑定什么事件?

首先,双向绑定,我个人认为应该分为 初始化绑定双向更新 两part。

初始化绑定,就是初始化时给表单元素绑定值,绑定事件,为双向更新做准备

双向更新,就是任意一边变化,同时能让另一个边更新

双向更新那是后话,只有一开始时成功执行绑定操作才会有之后 双向更新这个东西,所以,今天按顺序来了解两个part,从四个问题开始

1、v-model 怎么给表单绑定数据

2、v-model 绑定什么事件

3、v-model 怎么绑定事件

4、v-model 如何进行双向更新

TIP

v-model 还可以用在 自定义组件上,但是很明显,这次我们先不讲这一块,而是先将正常的表单使用

8af2042877e6826143185fb36690fce9.png

先看结论

我们先以 input text 类型讲解,对于其他的表单元素,流程都差不多,只是中间涉及的内容不同。所以就先讲个例子,然后具体在源码版全部一起说

1、怎么赋值?v-model 绑定的数据赋值给表单元素的 value 属性

2、怎么绑定事件?解析不同表单元素,配置相应的事件名和事件回调,在插入dom之前,addEventListener 绑定上事件

3、怎么双绑?外部变化,触发事件回调,event.target.value 赋值给model绑定的数据;内部变化,修改表单元素属性 value

看完结论,有点懵?我们来看看具体的内容,结果导向来进行学习

下面的讲解以下面这个为例

ecdedc0273fc3bb730d31b18b7d52270.png
1d988cf254a377185ebb6a06e067cce4.png

v-model 怎么给表单绑定数据

获取值流程

首先,上面例子解析后的渲染函数是下面这样(已简化,只保留表单值相关)

(

1、这个渲染函数是没有执行的 匿名函数。执行的时候,会绑定上下文对象为 组件实例

2、于是 with(this) 中的 this 就能取到 组件实例本身,with 的代码块 顶层作用域 就绑定为了 组件实例

3、于是 with 内部变量的访问,就会首先访问到 组件实例上。其中 name 的 获取,就会先从 组件实例上获取,相当于 vm.name。赋值完成后,domProps 就是下面这样

{

4、上面的 value 是 v-model 解析成的原生属性,保存在属于该节点 input 的 domProps 对象存储器中

绑定值流程

创建dom input 之后,插入dom input 之前,遍历该 input 的 domProps ,逐个添加给 input dom

简化后的代码像下面这样进行赋值

for

其中给节点赋值就是这样

input

8af2042877e6826143185fb36690fce9.png

v-model 绑定什么事件

不同的表单元素使用v-model,会绑定不同的 事件

change 事件

select,checkbox,radio

input 事件

这是默认事件,当不是上面三种表单元素时,会解析成 input 事件

比如 text、number 等 input 元素和 textarea

TIP

实际上关于 input 和 textarea 绑定的事件远不止 input 一个事件,但是涉及内容太多,打算放在源码版说明,这里先简单默认是 input 事件

8af2042877e6826143185fb36690fce9.png

v-model 怎么绑定事件

上面例子解析成下面的渲染函数(已简化,只保留事件相关)

with

解析事件流程

1解析不同表单元素,配置不同的事件

2拼装 事件回调函数,不同表单元素,回调不一样

3把 事件名和拼装回调 配套 保存给相应的表单元素的 on 事件存储器

什么时候绑定事件

生成 input dom 之后,插入input dom 之前

怎么绑

使用之前保存的 事件名和 事件回调,给 input dom 像下面这样绑定上事件

input

8af2042877e6826143185fb36690fce9.png

v-model 如何进行双向更新

双向,指的是 外部和内部

外部变化:用户手动改变表单值,输入或者选择

内部变化:从内部修改绑定值

内部变化

1、v-model 绑定了 name ,name 会收集到 本组件的 watcher

a. 下面渲染函数执行时,会绑定本身组件实例为上下文对象

b. name 访问的是 组件实例的 name

c. name 此时便收集到了 当前正在渲染的组件实例,当前渲染的实例是自己,于是收集到了自身的 watcher

(

如果你不懂 收集 watcher 什么意思,建议看下我的另一篇文章

【Vue原理】响应式原理 - 白话版

2、内部修改 name 变化,通知收集器内的 watcher 更新,所以本组件会更新,上面的渲染函数重新执行,便 重新从实例读取 name

c6ebb0711ebb4a63cbc9a762c291adc8.png

3、重新给 input dom 的 value 赋值,于是 页面就更新了

怎么赋值?那是回到第一个问题了,兄弟

外部变化

手动改变表单,事件触发,执行事件回调(下面这个),更新组件数据 name

function

更新内部数据流程

1、当事件触发的时候,会把 表单的值 赋值给 name

2、name 是从 组件实例上访问的

3、所以这次赋值会 直接改变组件实例的 name

回调怎么赋值给组件实例的name?

一开始不懂,所以不理解,也没查到,写了个例子,大概理解了意思

1、因为事件回调 在 with 里面声明

2、于是事件回调的 作用域链最顶层 就加上了一层 with 绑定的作用域

3、就算事件回调不在 with 中执行,事件回调中的 变量访问,也会先访问之前 with 绑定过的作用域,因为作用域链的最顶层

with举栗子

var

你认为 fn 执行的时候,会打印出什么呢?行了,给你看结果了

3d3084ea2c4ed56ff843f5ade542666f.png

好吧,再一次深刻认识到一个知识点,with 绑定作用域原来这么强,离开with执行,还是先访问他的作用域,脱离不出魔爪啊,强盗作用域

87e354f77e9fba0ae36122d6ad06fac1.png

回来总结!

于是当事件回调执行的时候,会 直接赋值 给 组件实例的name,这样便通过外部改变了内部数据

TIP

外部变化,本来可能会存在一种情况

a、手动修改表单后, 回调内会更新组件的值

b、组件的值更新之后,会通知组件更新,组件更新时,便又会重新把input 赋值一遍

非常多余的一步操作,所以这里,Vue做一个判断,判断旧值和 新值是否相等,不等才更新,关于旧值,会保存在 dom 的 _value 属性

8af2042877e6826143185fb36690fce9.png

总结

v-model 三要素

1、绑定属性

2、绑定事件

3、属性+事件组合完成双向更新

8af2042877e6826143185fb36690fce9.png

历史分享

【Vue原理】Vue源码阅读总结大会 - 序

【Vue原理】学会调试Vue源码

【Vue原理】响应式原理 - 白话版

【Vue原理】Props - 白话版

【Vue原理】月老Computed - 白话版

【Vue原理】Watch - 白话版

【Vue原理】Mixin - 白话版

【Vue原理】Methods - 源码版

【Vue原理】Filters - 源码版

8af2042877e6826143185fb36690fce9.png

最后

希望你认真阅读后,能豁然开朗。如果你懂了,我的目的也达到了,如果你还不懂,可以留言告诉我哦,百分百回复好吧

当然如果本文有任何描述不当的问题,欢迎后台联系本人,重谢

如果你认为有帮助的,谢谢点个赞。如果写得不对的地方,可以骂我

f717f44afe0fafce1e0895268f38e36e.png



推荐阅读
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • 深入解析:React与Webpack配置进阶指南(第二部分)
    在本篇进阶指南的第二部分中,我们将继续探讨 React 与 Webpack 的高级配置技巧。通过实际案例,我们将展示如何使用 React 和 Webpack 构建一个简单的 Todo 应用程序,具体包括 `TodoApp.js` 文件中的代码实现,如导入 React 和自定义组件 `TodoList`。此外,我们还将深入讲解 Webpack 配置文件的优化方法,以提升开发效率和应用性能。 ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
  • 解决Only fullscreen opaque activities can request orientation错误的方法
    本文介绍了在使用PictureSelectorLight第三方框架时遇到的Only fullscreen opaque activities can request orientation错误,并提供了一种有效的解决方案。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 如何优化MySQL数据库性能以提升查询效率和系统稳定性 ... [详细]
  • 在Linux系统中,网络配置是至关重要的任务之一。本文详细解析了Firewalld和Netfilter机制,并探讨了iptables的应用。通过使用`ip addr show`命令来查看网卡IP地址(需要安装`iproute`包),当网卡未分配IP地址或处于关闭状态时,可以通过`ip link set`命令进行配置和激活。此外,文章还介绍了如何利用Firewalld和iptables实现网络流量控制和安全策略管理,为系统管理员提供了实用的操作指南。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 本文详细介绍了定时器输入捕捉技术的原理及其应用。通过配置定时器通道的引脚模式为输入模式,并设置相应的捕获触发条件,可以实现对外部信号的精确捕捉。该技术在实时控制系统中具有广泛的应用,如电机控制、频率测量等场景。文中还提供了具体的配置步骤和示例代码,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 在 Vue 应用开发中,页面状态管理和跨页面数据传递是常见需求。本文将详细介绍 Vue Router 提供的两种有效方式,帮助开发者高效地实现页面间的数据交互与状态同步,同时分享一些最佳实践和注意事项。 ... [详细]
  • 本文全面解析了JavaScript中的DOM操作,并提供了详细的实践指南。DOM节点(Node)通常代表一个标签、文本或HTML属性,每个节点都具有一个nodeType属性,用于标识其类型。文章深入探讨了DOM节点的创建、查询、修改和删除等操作,结合实际案例,帮助读者更好地理解和掌握DOM编程技术。 ... [详细]
  • ButterKnife 是一款用于 Android 开发的注解库,主要用于简化视图和事件绑定。本文详细介绍了 ButterKnife 的基础用法,包括如何通过注解实现字段和方法的绑定,以及在实际项目中的应用示例。此外,文章还提到了截至 2016 年 4 月 29 日,ButterKnife 的最新版本为 8.0.1,为开发者提供了最新的功能和性能优化。 ... [详细]
  • JavaScript XML操作实用工具类:XmlUtilsJS技巧与应用 ... [详细]
  • Vue 实战基础教程第9讲:深入理解计算属性与侦听器的高效使用
    Vue 实战基础教程第9讲:深入理解计算属性与侦听器的高效使用 ... [详细]
author-avatar
北路新华
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有