这就要从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的

最新文章

  1. socket.io 中文手册 中文文档
  2. struts2的两个核心配置文件
  3. bzoj3876
  4. (转载)tarjan求割点
  5. Introduction to the Build Lifecycle
  6. SharePoint Search之(两)持续抓取Continues crawl
  7. NOIP2017 - 宝藏
  8. Python初级教程
  9. JVM内存结构--新生代及新生代里的两个Survivor区(下一轮S0与S1交换角色,如此循环往复)、常见调优参数
  10. 运用SharedPreferences“偷取”输入的信息
  11. win7+win10系统使用日常经验集锦
  12. ABP框架系列之二十:(Dependency-Injection-依赖注入)
  13. Ocelot中文文档-Not Supported
  14. shell 整数条件判断
  15. 牛客网-《剑指offer》-重建二叉树
  16. js实现裁剪头像上传编辑器
  17. OD 实验(五) - 对 PE 结构的简单分析
  18. 实现二叉树的基本操作(Java版)
  19. centos踩坑指南之安装composer
  20. AndroidStudio3.0 注解报错Annotation processors must be explicitly declared now. The following dependencies on the compile classpath are found to contain annotation processor.

热门文章

  1. js 变量作用域
  2. day6_自定义类型转换
  3. Rails6新增rails db:system:change更换数据库
  4. 蓝鲸DevOps深度解析系列(2):蓝盾流水线初体验
  5. __FILE__、__DIR__区别
  6. Robot Framework--ride使用说明2
  7. java Arrays常用方法
  8. php session 保存到redis 实现session的共享
  9. c# Expression 扩展
  10. Python中对字符串的操作