这就要从reactive开始讲起了,粗略的说,js的操作能引起页面上显示的改变,是因为该操作引起了组件的重新渲染,渲染会生成新的虚拟节点,新节点和旧节点会对比,操作浏览器的node进行改变。

vue实例以下简称vm

说具体点

data()方法的返回值以及watch,props,computed里面的属性,,在这之前都会被defineReactive方法重写get和set方法(get方法重写为调用的时候收集Dep这个静态变量指向的watcher,set方法调用的时候会notify收集的watchers,调用每个watcher的update--->run--->get方法)和methods里面的方法一起,被挂载到vm实例上(所以methods里面this.XXX才有用,因为调用method的是 vm,属性也在vm上)

-----------------所以如果想要对象(比如a)的属性b的set方法能引起重新渲染,必须在b被get的时候,收集到可以引起重新渲染的watcher。那么是什么时候收集的呢?

每一个vm有一个render Watcher,在mountComponent的时候生成,render Watcher的expOrFn方法是 vm._update(vm._render(), hydrating)--->vm.__patch__(prevVnode, vnode),(对比新旧虚拟节点,操作真实node),在这个过程中,vm._render()会按照Vue的<template>中的内容,为每一个子节点

生成属性,查看render的代码会发现有个with(this),这里this就是vm,就是要调用vm的属性的get方法给虚拟节点的属性赋值。然后再进行对比等操作。在这个过程中,被调用get方法的属性就会收集renderWatcher。

-----------------那为什么array[0]='a'这样的方法不会重新渲染?

因为array的0这个属性?,没有重写get和set方法

-----------------为什么pop push可以reactive?

比如a.b=c,reactive的过程是: observe(a)---> defineReactive(b)--->重写b的get方法之前先observe(c)。observe c的时候,如果判断c是一个数组,那么c的pop.、push等方法会重新指向,指向后的新方法,先调用Array原来来对应的方法,然后调用_ob_指向的observer的dep的notify方法,通知收集的watcher

-----------------对象的dep从哪里来?

上面说过,observe(c),new一个Observer 实例childOb,c的_ob_属性指向childOb,childOb里面有一个dep属性,而在b的重写的get方法中,会有childOb.dep.depend()的执行

-----------------灵魂第五问:既然是给b重写set和get的时候,给c的_ob_的dep收集Watcher,那么数组里面的元素比如array[0]=d,而d恰好是数组,为什么d.push也可以reactive?

在childOb.dep.depend()方法下面还有个if,如果属性指向的是个数组,直接递归收集。那么这时候如果是数组的元素是个对象,就不管了,只考虑数组 中的元素还是数组的情况。所以array[0]='a'是不能reactive的,但是array[0].push('a')是可以reactive的

Vue源码之----为什么Vue中Array的pop,push等方法可以reactive,而Array[0]='a'这样的方法不会reactive?的更多相关文章

  1. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

  2. Vue源码学习1——Vue构造函数

    Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...

  3. Vue源码学习二 ———— Vue原型对象包装

    Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...

  4. Vue源码学习三 ———— Vue构造函数包装

    Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...

  5. vue 源码学习三 vue中如何生成虚拟DOM

    vm._render 生成虚拟dom 我们知道在挂载过程中, $mount 会调用 vm._update和vm._render 方法,vm._updata是负责把VNode渲染成真正的DOM,vm._ ...

  6. Vue源码学习一 ———— Vue项目目录

    Vue 目录结构 可以在 github 上通过这款 Chrome 插件 octotree 查看Vue的文件目录.也可以克隆到本地.. Vue 是如何规划目录的 scripts ------------ ...

  7. 深入vue源码,了解vue的双向数据绑定原理

    大家都知道vue是一种MVVM开发模式,数据驱动视图的前端框架,并且内部已经实现了双向数据绑定,那么双向数据绑定是怎么实现的呢? 先手动撸一个最最最简单的双向数据绑定 <div> < ...

  8. vue源码构建代码分析

    这是xue源码学习记录,如有错误请指出,谢谢!相互学习相互进步. vue源码目录为 vue ├── src #vue源码 ├── flow #flow定义的数据类型库(vue通过flow来检测数据类型 ...

  9. 【Vue】VUE源码中的一些工具函数

    Vue源码-工具方法 /* */ //Object.freeze()阻止修改现有属性的特性和值,并阻止添加新属性. var emptyObject = Object.freeze({}); // th ...

随机推荐

  1. Vue小项目二手书商城:(四)详情页和购物车(emit、prop、computed)

    实现效果: 点击对应商品,对应的商品详情页出现,详情页里面还有“Add to cart”按钮和“×”退出按钮. 点击“Add to cart”可以将商品加入购物车,每件商品只能添加一次,如果把购物车的 ...

  2. 使用sphinx制作接口文档并托管到readthedocs

    此sphinx可不是彼sphinx,此篇是指生成文档的工具,是python下最流行的文档生成工具,python官方文档即是它生成,官方网站是http://www.sphinx-doc.org,这里是一 ...

  3. Mysql 索引之B+tree

    InnoDB使用的是聚簇索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶 ...

  4. HBase RegionServer Splitting 流程

    RegionServer Splitting 实现 HBase 中的写请求由 Region Server 处理,这些数据首先存储在 memstore (RegionServer 里的一个存储系统)里. ...

  5. Java程序设计的第一次作业1

  6. Click event doesn't work on dynamically generated elements

    I couldn't get live or delegate to work on a div in a lightbox (tinybox). I used setTimeout successf ...

  7. mysql Access denied for user root @localhost (using password:YES)错误

    C:\AppServ\MySQL> mysql -u root -p Enter password:  ERROR 1045 (28000): Access denied for user 'r ...

  8. 记一次mybatis bindingexception 问题排查

    看到的错误信息如出一辙都是这样的:Method threw 'org.apache.ibatis.binding.BindingException' exception.Invalid bound s ...

  9. myEclipse和eclipse从debug视图自动跳回default视图。

    本来是吐槽文,找到了解决的插件,就改改标题了. debug的时候,可以从default视图自动跳转到debug视图,退出debug的时候,却不能自动切换回default视图. https://bugs ...

  10. springcloud-spring cloud config统一配置中心

    统一配置中心 为什么需要统一配置中心? 统一配置中心顾名思义,就是将配置统一管理,配置统一管理的好处是在日后大规模集群部署服务应用时相同的服务配置一致,日后再修改配置只需要统一修改全部同步,不需要一个 ...