Vue2响应式原理分析(数据代理与数据劫持)

综述:

  • 我们都知道,每个Vue的应用都是通过new一个Vue构造函数从而创造出来一个vm实例对象,el(elect)配置项为通过id选择器#root选择index页面中的根dom元素进行绑定,data配置项则为vue模板中用到的源数据。

  • Vue实例在创建时,会接收data对象,并遍历此对象所有的属性,并使用Object.defineProperty将属性全部转为getter/setter,以便追踪属性的变化(obs)。当用户在View层进行操作时,ViewModel能感知到变化并对Model层的数据进行更新,反之亦然。

数据代理:

  • 数据代理即为通过操作对象a来直接触碰对象b达到修改对象b的目的的操作。

  • 在Vue响应式原理中,数据代理则体现在了data配置项通过一系列操作(下文中会分析)赋到了vm实例的_data属性上,然后vm对_data做了代理,即通过Object.defineProperty为vm实例响应式地添加了_data中的属性,从而使Vue模板中不必使用this._data.name来使用,直接使用this.name即可。(Ps:凡是vm实例身上的属性,在Vue模板中均可直接使用,即插值语句{{name}}即可)

  • 而在某种意义上_data与data相同。

  

tips:
  • 一旦data中数据发生改变,那么页面中用到该数据的地方自动更新。

  • _data代理了data,vm代理了_data。

  • 通过defineProperty()方法为vm添加_data中有的属性,再提供setter/getter。

  • 疑点:data经加工后vm._data===data的原因,修改data属性能够重新渲染页面的原因。

  • 原数据data已经被obs劫持,只能通过obs访问。

  • _data里面的属性已经变成访问器属性。

  • _data直接赋值new Vue时传入的data,所以指向同一个地址,二者无区别。

数据劫持:

        上文中提到某种意义上data===_data,这里将介绍数据代理图示中黄色线中所做的操作。

  • 首先data代表vm实例配置项中的源数据,其需要经过加工后,赋给vm._data,所以说二者相同。

  •  至于是如何加工的,下图中的代码做了模拟,用到了观察者对象。

  • 首先data模拟的是未经加工的源数据,将data传入了观察者对象(即obs)的构造函数作为参数(即obj)。传入的为对象data,为其地址。

 
tips:    

        在Java中,函数参数传递的是对象的引用(内存地址),而不是对象本身。当一个对象作为参数传递给一个函数时,实际上是将对象的引用(内存地址)传递给了函数,函数中对该对象的操作会影响到原始对象。因此,在函数内部对传递的对象进行修改时,会影响到原始对象的状态。

       由此,下文中obs,data,._data操作的为同一块内存,故data即为._data

  • 在观察者对象(即obs)中所作的操作就是把obj(即传入的data源数据)的所有的属性名提取出来,为这个obs通过Object.defineProperty的形式响应式地(即getter、setter)添加data中的所有属性(若有深层对象则递归添加)。

  • 现在这个obs身上有了data中的所有属性及其响应式。

  • 之所以采用obs,是为了避免递归死循环。

  • 在下图代码中,然后就是将这个构造好的obs连续赋给data及vm._data(实际中为引用传参)

  • 在此时,若._data属性值修改,很明显将触发对应属性匹配的setter,而这个setter具有执行解析模板、生成虚拟dom、新旧dom的diff算法对比、生成新页面的功能逻辑。

  • 而数据劫持就是体现在这个setter的实际操作中。

  • 在某种意义上,观察者obs相当于一个辅助对象。

  • 在下图中可以看到,._data身上属性的setter和getter,其对源data通过obs套了一层代理,系统命名为reactiveSetter和reactiveGetter,因为其中封装了更新页面的逻辑操作,所以不同。

  • 而且可以看到,._data实际上即为Observer对象,即._data中属性改动将触发Setter渲染页面。

  • 当._data中任意一个reactiveSetter被触发后, 都会使Vue重新解析页面,所以说属性修改后页面重新解析的关键在于Setter。

Vue响应式整体流程: 

  • Vue框架是一个MVVM框架。

(详见我的上一篇博文)MVVM模型

  •   VM即为我们new出来的实例对象,M即为Model(data源数据),V即为View视图(Vue模板template) 。

  • 简而言之,就是在Vue中,ViewModel就是Vue实例。Vue实例在创建时,会接收data对象,并遍历此对象所有的属性,并使用Object.defineProperty将属性全部转为getter/setter,以便追踪属性的变化(obs)。当用户在View层进行操作时,ViewModel能感知到变化并对Model层的数据进行更新,反之亦然。

DOM Listeners:
  • DOM Listeners是对DOM结构进行监听,若发生数据改动则通过DOM listenersDOM监听器将数据传到Model中。

  • 即当vm身上的根属性发生改动(即DOM结构发生改变)后,由于vm对其属性._data做了一层数据代理,其对根属性的改动将通过vm身上的该根属性对应的setter来实现对._data中的对应属性的改动,而._data中属性改动又将通过obs传导到Model中。

Data Bindings:
  • Data Bindings是把Model的数据通过Data Bindings数据绑定送到Vue的模板实例对象上。

  • 即data源数据通过obs传导到._data中,一般情况下vm实例又对._data进行了代理,从而通过vm实例对._data的代理实现了将Model(data)中传来的数据绑定送到Vue模板实例对象的操作。

  • 又因为使用Object.defineProperty,故实现的是使用getter和setter的数据双重绑定操作。

  •  改属性页面变化原理大致如下图所示:

(其中Observer的setter与getter即为上文中提到的reactiveGetter/reactiveSetter。)

 

  •  以下代码为简单的响应式模拟(Object.defineProperty应用):
//源数据
let person = {name:'张三',age:18
}
//模拟Vue2中实现响应式
let p = {}
Object.defineProperty(p,'name',{configurable:true,get(){ //有人读取name时调用return person.name},set(value){ //有人修改name时调用console.log('有人修改了name属性,我发现了,我要去更新界面!')person.name = value}
})
Object.defineProperty(p,'age',{get(){ //有人读取age时调用return person.age},set(value){ //有人修改age时调用console.log('有人修改了age属性,我发现了,我要去更新界面!')person.age = value}
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2804502.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

C语言-数组指针与指针数组

一、简介 对于使用C语言开发的人来说,指针,大家都是非常熟悉的。数组,大家也同样熟悉。但是这两个组合到一起的话,很多人就开始蒙圈了。这篇文章,就详细的介绍一下这两个概念。 指针数组和数组指针,听起来非…

【服务器数据恢复】通过reed-solomon算法恢复raid6数据的案例

服务器数据恢复环境: 一台网站服务器中有一组由6块磁盘组建的RAID6磁盘阵列,操作系统层面运行MySQL数据库和存放一些其他类型文件。 服务器故障: 该服务器在工作过程中,raid6磁盘阵列中有两块磁盘先后离线,不知道是管理…

在Linux操作系统的ECS实例上安装hadoop

目录 1. java(jdk)2. Hadoop3. 配置文件4. 启动Hadoop服务(搭建伪分布式环境) 1. java(jdk) yum list java* :列出所有名称中包含“java”字样的软件包yum install java-1.8.0-openjdk.x86_64:选择自己想要的版本。这里我选择jav…

DataGrip 2023:让数据库开发变得更简单、更高效 mac/win版

JetBrains DataGrip 2023是一款功能强大的数据库IDE,专为数据库开发和管理而设计。通过DataGrip,您可以连接到各种关系型数据库管理系统(RDBMS),并使用其提供的一组工具来查询、管理、编辑和开发数据库。 DataGrip 2023 软件获取 DataGrip 2…

分散的产品开发团队

分散的产品开发团队指的是各个团队或成员在地理位置上分布在不同地方,通过互联网和现代通讯技术进行协作和沟通,以共同完成产品开发任务的团队模式。 这种团队模式的优势在于可以充分利用各地的人才资源,降低团队的管理和协作成本&#xff0…

【Ubuntu】使用WSL安装Ubuntu

WSL 适用于 Linux 的 Windows 子系统 (WSL) 是 Windows 的一项功能,可用于在 Windows 计算机上运行 Linux 环境,而无需单独的虚拟机或双引导。 WSL 旨在为希望同时使用 Windows 和 Linux 的开发人员提供无缝高效的体验。安装 Linux 发行版时&#xff0c…

云HIS系统源码,基于云计算技术的B/S架构的云HIS系统,二甲医院信息管理系统

云HIS系统源码,采用云端SaaS服务的方式提供 基于云计算技术的B/S架构的云HIS系统,采用云端SaaS服务的方式提供,使用用户通过浏览器即能访问,无需关注系统的部署、维护、升级等问题,系统充分考虑了模板化、配置化、智能…

vscode + wsl2 + xmake快速构建c语言编译调试环境

前言 使用这一套是我觉得最方便的,wsl2使得我可以不用脱离windows,且无需安装庞大且臃肿虚拟机。vscode让我可以更加方便快捷的编辑代码,而xmake是一站式的工程构建工具且作者就是中国人文档啥的群啥的都是中文,比起cmake makefi…

python统计分析——线性模型的预测和评估

参考资料:用python动手学统计学 1、导入库 # 导入库 # 导入数据处理的库 import numpy as np import pandas as pd import scipy as sp from scipy import stats # 导入绘图的库 from matplotlib import pyplot as plt import seaborn as sns sns.set() # 导入估计…

BERT学习笔记

论文:《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》,2019 代码:[tensorflow],[pytorch] 来源:李沐精度BERT 0、摘要 与之前模型的区别: GPT考虑的是一个单向…

OLTP、OLAP与HTAP、HSAP详解

HTAP、HSAP是OLAP与OLTP综合需求驱动下的新的数据库系统,既满足事务处理,又满足大规模分析查询,并且是基于一套系统下实现。 本节首先我们要了解服务于分析的区别。相当多从应用角度对数据处理分类的划分,大致可以分为Transactio…

计算机网络-网络互联与互联网(一)

1.常用网络互联设备: 1层物理层:中继器、集线器2层链路层:网桥、交换机3层网络层:路由器、三层交换机4层以上高层:网关 2.网络互联设备: 中继器Repeater、集线器Hub(又叫多端口中继器&#xf…

PyTorch概述(二)---MNIST

NIST Special Database3 具体指的是一个更大的特殊数据库3;该数据库的内容为手写数字黑白图片;该数据库由美国人口普查局的雇员手写 NIST Special Database1 特殊数据库1;该数据库的内容为手写数字黑白图片;该数据库的图片由高…

Django学习记录04——靓号管理整合

1.靓号表 1.1 表结构 1.2 靓号表的构造 class PrettyNum(models.Model): 靓号表 mobile models.CharField(verbose_name"手机号", max_length11)# default 默认值# null true,blank true 允许为空price models.IntegerField(verbose_name"价…

学校档案室管理制度内容

学校档案室管理制度是指对学校档案室进行管理的规定和流程。以下是一个示例的学校档案室管理制度的内容: 1.档案室的管理部门和责任人员: 学校档案室由学校行政部门负责管理,行政部门指定专门的档案管理员负责档案室的日常管理工作。 2.档案室…

ElasticSearch之单值多字段查询以及dis max query

写在前面 在查询中经常有这样的查询场景,我们只有一个输入框,但是输入的值需要同时对多个字段进行查询,这就是单值多字段的查询,像下图: 1:例子 首先来准备测试数据: DELETE blogs PUT /bl…

记录 | docker内执行apt update报错GPG error

1. 执行 sudo apt-get update 命令时遇到这个错误,是服务器没有这个公钥的意思 rootadmin:~# sudo apt-get update Get:1 https://download.docker.com/linux/ubuntu focal InRelease [36.2 kB] Err:1 https://download.docker.com/linux/ubuntu focal InRelease T…

基于Python网络爬虫的IT招聘就业岗位可视化分析推荐系统

文章目录 基于Python网络爬虫的IT招聘就业岗位可视化分析推荐系统项目概述招聘岗位数据爬虫分析系统展示用户注册登录系统首页IT招聘数据开发岗-javaIT招聘数据开发岗-PythonIT招聘数据开发岗-Android算法方面运维方面测试方面招聘岗位薪资多维度精准预测招聘岗位分析推荐 结语…

Linux之ACL访问控制列表

一、ACL权限的介绍 1.1 什么是ACL 访问控制列表(ACL)是一种网络安全技术,它通过在网络设备(如路由器、交换机和防火墙)上定义一系列规则,对进出接口的数据包进行控制。这些规则可以包含“允许”&…

【Java EE初阶二十四】servlet的深入理解

1. Servlet API 的学习 下面主要学习这三个类,就已经可以完成 Servlet 的大部分开发了; 1. Httpservlet 2. HttpServletRequest 3. HttpServletResponse 2. Httpservlet的学习 2.1 Httpservlet在tomcat的工作原理 写一个 Servlet 代码,往往都…