虾米带你轻松搞定Vuejs 系列

(十五)Vue.js 依赖收集原理

一周没有整理笔记了,今天继续。前边一节笔记记录了vue.js的响应式系统的内部机制原理,今天我们整理一下响应式系统的依赖收集。

什么是依赖收集

直接描述术语可能有点唐突。我们在这里写2个小例子,来加深一下代码理解,再来解释依赖收集。示例一:

初始化的html结构和初始化的data现在已经有了,这个时候发现address这个属性并没有在html结构中出现。接下来我们动态修改data中的address属性的值。

我们看一下vue的内部数据变成了什么,不妨看一下。

这里我们修改了data中的address的数据,但是因为视图中不确定需要用到address,所以我们并不需要触发上篇笔记中的cb 方法来更新视图,简单的说如果这里触发了cb 方法,说明你的逻辑是不正确的。可能大家还是不清楚,再来一个示例,假如有一个全局对象,我们会在多个Vue对象中用到它并展示。示例二:

最后执行全局全局属性的修改,这里通过数据看不出来,这里需要分析内部,通过通知test1、test2两个vm实例进行视图的更新,依赖收集会让 name 属性这个数据知道,也就实现了俩个地方依赖全局数据,全局诗句变化时候需要通知各自的视图。

最终我们形成数据与视图的一种对应关系,我们简单画一下:

可是我发现我还是不够清晰。怎么又多了一个Dep呢?我再来探索一下Dep或者说依赖收集怎么实现的。

Dep(defineProperty)

首先,我先实现一个简单的订阅者Dep,它是用来存放Watcher对象,也就是我们说的观察者对象。

解释一下这段代码。主要是做了2件事情:

  1. 调用addSub方法添加一个当前Dep对象的Watcher订阅操作
  2. 调用notify方法通知当前Dep对象的subs中的所有Watcher触发更新

Watcher(观察者)

这段代码很简单,这里不多说了。

依赖收集

接下来我们修改一下 defineReactive 以及 Vue 的构造函数,来完成依赖收集。

我们在闭包中增加了一个 Dep 类的对象,用来收集 Watcher 对象。在对象被「读」的时候,会触发 reactiveGetter 函数把当前的 Watcher 对象(存放在 Dep.target 中)收集到 Dep 类中去。之后如果当该对象被「写」的时候,则会触发 reactiveSetter 方法,通知 Dep 类调用 notify 来触发所有 Watcher 对象的 update 方法更新对应视图。

总结

首先在 observer 的过程中会注册 get 方法,该方法用来进行依赖收」。在它的闭包中会有一个 Dep 对象,这个对象用来存放 Watcher 对象的实例。其实依赖收集的过程就是把 Watcher 实例存放到对应的 Dep 对象中去。get 方法可以让当前的 Watcher 对象(Dep.target)存放到它的 subs 中(addSub)方法,在数据变化时,set 会调用 Dep 对象的 notify 方法通知它内部所有的 Watcher 对象进行视图更新。

这是 Object.defineProperty 的 set/get 方法处理的事情,那么依赖收集的前提条件还有两个:

  1. 触发 get 方法;
  2. 新建一个 Watcher 对象。

这个我们在 Vue 的构造类中处理。新建一个 Watcher 对象只需要 new 出来,这时候 Dep.target 已经指向了这个 new 出来的 Watcher 对象来。而触发 get 方法也很简单,实际上只要把 render function 进行渲染,那么其中的依赖的对象都会被读取,这里我们通过打印来模拟这个过程,读取 test 来触发 get 进行依赖收集。

本笔记介绍了依赖收集的过程,配合之前的响应式原理,已经把整个响应式系统介绍完毕了。其主要就是 get 进行依赖收集。set 通过观察者来更新视图,配合下图仔细捋一捋,相信一定能搞懂它!

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值