Vue中Object和Array数据变化侦测原理
在学完Vue.js框架,完成了一个SPA项目后,一直想抽时间找本讲解Vue.js内部实现原理的书来看看,经过多方打听之后,我最后选择了《深入浅出Vue.js》这本书。然而惭愧的是,这本书已经买了将近一个多月了吧,自己中间却因为一些杂七杂八的事情,一直没有静下心来好好看书。今天,终于翻开了这本书,阅读了前三章的内容,目前感觉这本书写得还不错。因为经常看到关于Vue.js中双向数据绑定的问题,自己也在网上浏览过一些博客,然而基本上都是千篇一律而又不知所云,很多都是直接上来就是代码,说实话刚开始很多名词我都不知道是啥,比如什么依赖收集、发布订阅什么的。现在看了这本书上讲的,感觉讲得挺清楚的,我终于知道之前那些博客里都在说的依赖是个啥了。所以,决定将我现在看了的关于变化侦测部分的内容整理记录如下:
一、Object的变化侦测
说实话,在看这本书之前,我哪里知道原来Vue.js中的变化侦测还要分Object和Array啊。如果有人问我:“你知道Vue中的双向数据绑定如何实现的吗?”那我大概也只能答一个:“嗯,在Vue中使用指令v-model可以实现数据的双向绑定,其内部是通过Object.defineProperty属性来重新设置getter和setter函数来对数据变化进行侦测,从而达到数据双向绑定的。”是的,我最多就只能凑出这么一句话了,还不准确。而现在才发现,原来不同数据类型的变化侦测还不一样啊。好了,不废话了,开始进入正题。
“变化侦测就是侦测数据的变化。当数据发生变化时,要能侦测到并发出通知。Object可以通过Object.defineProperty将属性转换成getter/setter的形式来追踪变化。读取数据时会触发getter,修改数据时会触发setter。我们需要在getter中收集有哪些依赖使用了数据。当setter被触发时,去通知getter中收集的依赖数据发生了变化。收集依赖需要为依赖找一个存储依赖的地方,为此我们创建了Dep,它用来收集依赖、删除依赖和向依赖发送消息等。所谓的依赖,其实就是Watcher。只有Watcher触发的getter才会收集依赖,哪个Watcher触发了getter,就把哪个Watcher收集到Dep中。当数据发生变化时,会循环依赖列表,把所有的Watcher都通知一遍。
整个过程就是Data通过Observer转换成了getter/setter的形式来追踪变化。当外界通过Watcher读取数据时,会触发getter从而将Watcher添加到依赖中。当数据发生了变化时,会触发setter,从而向Dep中的依赖发送通知。Watcher接收到通知后,会向外界发送通知,变化通知到外界后可能会触发视图更新,也有可能触发用户的某个回调函数等。”
二、Array的变化侦测
从书中所讲来看,Array的变化侦测比Object要麻烦一点,它是通过创建拦截器去覆盖数组原型的方式来追踪变化。为了不污染全局Array.prototype,我们在Observer中只针对那些需要侦测变化的数组使用_proto_来覆盖原型方法。Array收集依赖的方式和Object一样,都是在getter中收集。但是由于使用依赖的位置不同,数组要在拦截器中向依赖发消息,所以不能像Object那样保存在defineReactive中,而是把依赖保存在了Observer实例上。在Observer中,我们对每个侦测了变化的数据都标上印记_ob_,并把this保存在_ob_上。一方面是为了标记数据是否被侦测了变化,另一方面可以很方便地通过数据取到_ob_,从而拿到Observer实例上保存的依赖。当拦截到数组发生变化时,向依赖发送通知。
除了侦测数组自身的变化外,数组中元素发生的变化也要侦测。调用observerArray方法将数组中的每一个元素都转换成响应式的并侦测变化。当用户使用push等方法向数组中新增数据时,新增的数据也要进行变化侦测。我们使用当前操作数组的方法来判断,从参数中将新增数据提取出来,然后使用observerArray对新增数据进行变化侦测。
对于数组类型的数据,一些语法无法追踪到变化,只能拦截原型上的方法,而无法拦截数组特有的语法,例如使用length清空数组的操作就无法拦截。
说明:以上内容大多摘自《深入浅出Vue.js》,此文仅为自己的学习笔记
Vue中Object和Array数据变化侦测原理的更多相关文章
- 手牵手,从零学习Vue源码 系列二(变化侦测篇)
系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 陆续更新中... 预计八月中旬更新完毕. 1 概述 Vue最大的特点之一就是数据驱动视 ...
- 详解Vue 如何监听Array的变化
详解Vue 如何监听Array的变化:https://www.jb51.net/article/162584.htm
- Vue props中Object和Array设置默认值
Vue中,在props中设置Object和Array的默认值 seller: { type: Object, default() { return {} } } seller: { type: Obj ...
- 深入浅出 - vue变化侦测原理
废话真多!!! 其实在一年前我已经写过一篇关于 vue响应式原理的文章,但是最近我翻开看看发现讲的内容和我现在心里想的有些不太一样,所以我打算重新写一篇更通俗易懂的文章. 我的目标是能让读者读完我写的 ...
- 如何在Vue中使用Mockjs模拟数据的增删查改
之前一直使用json-server在前端开发时,搭建本地数据接口测试,但有时又需要将做好的项目放于 github page上做项目演示.在本地时,json server很好使用,但一旦放在github ...
- js中或者vue中 Object.assign()用法详解
Object.assign()是浅拷贝. 合并对象 var o1 = { a: 1 }; var o2 = { b: 2 }; var o3 = { c: 3 }; var obj = Object. ...
- Vue学习之--------列表排序(ffilter、sort、indexOf方法的使用)、Vue检测数据变化的原理(2022/7/15)
文章目录 1.列表排序 1.1 .代码实例 1.2 .测试效果 1.3.需要掌握的前提知识 2.Vue监测数据变化的原理 2.1.代码实例 2.2 .测试效果 3.Vue检测数据的原理 3.1 基本知 ...
- vue 中使用 AJAX获取数据的方法
在VUE开发时,数据可以使用jquery和vue-resource来获取数据.在获取数据时,一定需要给一个数据初始值. 看下例: <script type="text/javascri ...
- 在pycharm中批量插入表数据、分页原理、cookie和session介绍、django操作cookie
昨日内容回顾 ajax发送json格式数据 ''' 1. urlencoded 2. form-data 3. json ''' 1. ajax $.ajax({ data: JSON.stringi ...
随机推荐
- 扩展LLVM:添加指令、内部函数、类型等
扩展LLVM:添加指令.内部函数.类型等 Introduction and Warning Adding a new intrinsic function Adding a new instructi ...
- NVIDIA Turing Architecture架构设计(下)
NVIDIA Turing Architecture架构设计(下) GDDR6 内存子系统 随着显示分辨率不断提高,着色器功能和渲染技术变得更加复杂,内存带宽和大小在 GPU 性能中扮演着更大的角色. ...
- Nsight Compute Profilier 分析
profiler报告包含每次内核启动分析期间收集的所有信息.在用户界面中,它包含一个包含常规信息的标题,以及用于在报告页面或单个收集的启动之间切换的控件.默认情况下,报告以选定的详细信息页面开始. 页 ...
- Headline 项目总结中
目录 1.项目准备 1.1 rem适配 1.2 通用样式CSS 1.3删除测试代码 1.4Git托管 2.login页面 2.1 页面布局和表单校验 2.2login页的接口抽取 2.5.loadin ...
- 手把手使用Python语音识别,进行语音转文字
0. 太长不看系列,直接使用 在1.2官网注册后拿到APISecret和APIKey,直接复制文章2.4demo代码,确定音频为wav格式,采样率为16K,在命令行执行 python single_s ...
- 在Visual Studio 中使用git——同步到远程服务器-上(十一)
在Visual Studio 中使用git--什么是Git(一) 在Visual Studio 中使用git--给Visual Studio安装 git插件(二) 在Visual Studio 中使用 ...
- 液晶显示系列(2)之黑色背景的PPT更省电环保吗?常黑与常白型LCD
原文地址点击这里: 数年前听过一个培训师讲课,他的电脑课件PPT背景颜色是黑色的?美其名曰:黑色省电环保!当时讲台下听课的那些菜鸟们(也包括区区在下)深以为然,不由得心中竖起大拇指:这老师有水平,境界 ...
- Android开发问题之Installation failed due to invalid URI!
真机调试遇到以下问题: [2017-07-20 13:43:53 - VCL02PANEL] Installation failed due to invalid URI![2017-07-20 13 ...
- 生成工作区设置文件settings.json
先Ctrl+Shift+P,然后输入setting搜索 找到工作区设置(工作区,仅在当前打开的界面下生效,文档位置与根目录/.vscode/setting.json(可自己创建,也可不创建)) 选择之 ...
- AcWing 244. 谜一样的牛
有n头奶牛,已知它们的身高为 1~n 且各不相同,但不知道每头奶牛的具体身高. 现在这n头奶牛站成一列,已知第i头牛前面有a头牛比它低,求每头奶牛的身高. #include<bits/stdc+ ...