在学完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》,此文仅为自己的学习笔记

转载于:https://www.cnblogs.com/smalldy/p/11256875.html

Vue中Object和Array数据变化侦测原理相关推荐

  1. 解决Vue中Object.assign清空数据的报错

    想清空Vue中的data数据报错也许是没有改变this指向的原因可以试着用call等方便改变this指向例如 Object.assign(this.$data, this.$options.data. ...

  2. Vue中watch监听数据变化以及watch中各属性详解

    watch使用的几种方法 通过watch监听data数据的变化,数据发生变化时,就会打印当前的值 data(){return {msg: '你在想屁吃!',info: '555...',} } wat ...

  3. vue打开后端html文件,vue中怎么请求后端数据?

    vue中怎么请求后端数据?下面本篇文章给大家介绍一下vue 请求后台数据.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. vue 请求后台数据 需要引用vue-resource 安装 ...

  4. vue定时ajax获取数据,vue 中使用 AJAX获取数据的方法

    在VUE开发时,数据可以使用jquery和vue-resource来获取数据.在获取数据时,一定需要给一个数据初始值. 看下例: new Vue({ el:'#app', data:{data:&qu ...

  5. 在Vue中异步加载数据渲染到Dom

    在Vue中异步加载数据渲染到Dom 问题 <div v-for="o in resmessage" :key="o" class="text i ...

  6. 理解vue中less的scoped和/deep/工作原理

    理解vue中less的scoped和/deep/工作原理 scoped /deep/ 实战 总结 scoped vue项目一般是单页面.多组件,整个项目共用一个css样式表,有时候我们在写组件的过程中 ...

  7. Vue:array的变化侦测

    CSDN话题挑战赛第2期 参赛话题:学习笔记 学习之路,长路漫漫,写学习笔记的过程就是把知识讲给自己听的过程.这个过程中,我们去记录思考的过程,便于日后复习,梳理自己的思路.学习之乐,独乐乐,不如众乐 ...

  8. Vue props中Object和Array设置默认值

    Vue中,在props中设置Object和Array的默认值 seller: {type: Object,default() {return {}} } seller: {type: Object,d ...

  9. mock模拟的数据能增删改查吗_如何在Vue中使用Mockjs模拟数据的增删查改

    之前一直使用json-server在前端开发时,搭建本地数据接口测试,但有时又需要将做好的项目放于 github page上做项目演示.在本地时,json server很好使用,但一旦放在github ...

最新文章

  1. linux的共享内存,linux共享内存实际在哪里?
  2. 【HDOJ】1754 I Hate It
  3. android界面基本属性
  4. C# 学习笔记(16)ComboBox下拉列表框宽度自适应
  5. Hadoop-MapReduce 入门
  6. android 动态地改变某控件的大小
  7. java 获取属性值和设置属性值
  8. .o文件 linux生成,vmlinux.o 生成
  9. 【DL-CV】正则化,Dropout
  10. Linux下如何使用gcc编译器,Linux下gcc编译器的使用总结
  11. Vuforia3D模型上传
  12. 高质量编程之编译警告级别
  13. Quartus ll显示30天到期
  14. 【windows】Windows电脑怎么卸载服务/删除服务?
  15. 自定义形状的ImageView制作
  16. fatal error: gnu/stubs-32.h: No such file or directory
  17. 关于win7 环境下安装docker容器的步骤 以及过程中的问题解决
  18. python变量名可以用下划线开头吗_python以下划线开头的变量和函数的作用
  19. st_atime、st_mtime和st_ctime
  20. 2019 年 Vue 高手特训营

热门文章

  1. python document_python-docx 常用方法
  2. oracle10g配置失败,求解决装oracle10g的时候EM配置失败问题
  3. ieee期刊_机器人领域主要国际会议与期刊列表
  4. 水利水电工程与计算机技术应用,水利水电施工中计算机的应用
  5. linux hook 任意内核函数,linux内核中的hook函数详解
  6. linux数据库能看到系统执行了哪些命令,DB2数据库在linux操作系统的指令有哪些?...
  7. 英语发音规则---C字母
  8. BZOJ1036[ZJOI2008]树的统计——树链剖分+线段树
  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统(67)-MVC与ECharts
  10. 《Linux Device Drivers》第十六章 块设备驱动程序——note