vue源码学习之变化侦测

一、数据驱动视图

  • 用户操作或者后端返回数据引起数据变化,从而导致页面变化,这就是数据驱动视图。
  • 公式: UI = render(state), vue就充当了render的角色,当发现state发生变化的时候,就会通过数据监测,从而反应在页面UI上。

二、变化侦测

  • 所谓的变化侦测就是追踪数据的变化。
  • angular采用脏检查机制: 对脏数据的检查就是脏检查,比较ui和后台数据是否一致。 只有当ui事件或者网络请求,定时器延迟事件,才会触发脏检查。angular每一个绑定到ui的数据就会有一个$watch对象。一次脏检查就是调用一次$apply()或者$digest(),将数据中最新的值呈现在界面上
  • react是通过对比虚拟DOM来实现变化侦测。

三、vue中的数据监测和依赖收集

3.1 Object的变化侦测

  • vue采用object.defineProperty()监听属性,并把这个属性的读和写分别使用get()set()进行拦截
  • 使用observer类来将正常的object转换成可观测的对象;变成可观测对象以后,就可以监听数据变化,当数据变化后就要通知视图更新。所以我们要为谁用到了这个对象创建一个依赖管理器,谁依赖了这个数据,把这个数据所有的依赖都管理起来,当数据发生变化的时候,就去对应的依赖管理器中中,把每个依赖都通知一遍。这就是依赖收集。
  • 谁用到了数据,就代表一定会去读取数据,所以可以在getter里收集依赖,同样,数据变化也会触发setter,所以总结一句话就是 在getter中收集依赖,在setter中派发更新

3.1 依赖管理器和依赖

  • 调用dep.depend()收集依赖,在setter中利用dep.notify()通知所有依赖更新;
  • 所谓的依赖,也就是使用数据者,我们为使用数据者创建一个Watcher类。谁用到了数据,谁就是依赖,我们就为谁创建一个Watcher实例.也就是说当数据发生变化时,不直接去通知依赖更新,而是通知依赖对应的watcher,由watcher去更新真正的视图。Watcher先把自己设置到全局唯一的指定位置(window.target),然后读取数据。因为读取了数据,所以会触发这个数据的getter。接着,在getter中就会从全局唯一的那个位置读取当前正在读取数据的Watcher,并把这个watcher收集到Dep中去。收集好之后,当数据发生变化时,会向Dep中的每个Watcher发送通知。通过这样的方式,Watcher可以主动去订阅任意一个数据的变化。

3.2 Array的变化侦测(数据劫持)

  • 通过以上方法可以实现对对象的数据侦测,通过Observer方法把数据变成响应式,当外界通过Watcher读取数据时,会触发getter从而将Watcher添加到依赖中。当改变了数据,会触发setter,从而向Dep类中的依赖发送通知。Watcher接收到通知后,会向外界发送通知,变化通知到外界后可能会触发视图更新,也有可能触发用户的某个回调函数等。
  • 对于数组的响应式则采用了不一样的方式.因为因为对于Object数据我们使用的是JS提供的对象原型上的方法Object.defineProperty,但是对于数组检测的思路还是一样的。
  • 因为arr的数据始终还是存放在object数据对象里,所以Array型数据还是在getter中收集依赖。主要是重写数组的方法,利用数组拦截器,拦截在数组是和Array.prototype之间。Array原型中可以改变数组自身方法的内容有7个,push, pop, shift, unshift, splice, sort, reverse,对这7个方法,当我们调用者7个方法的时候实际上执行的是被拦截的方法,再指向自己的方法。
  • 如何通知依赖: 通过__ob__属性获取到Observer类,然后就可以访问到其依赖管理器,就可以通知依赖了。
  • 对新增元素的劫持,对splice, push, unshift方法进行处理,拿到新增元素进行处理
  • 缺点: 对于取下标的方式,无法侦测到。所以新增了vue.setvue.delete
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值