Vue中Observer类中dep属性

最近在看vue源码的时候遇到一个问题
在创建Observer时会给observer实例创建一个依赖Dep


export class Observer {
  value: any;
  dep: Dep; // <---------这里
  vmCount: number; // number of vms that has this object as root $data

  constructor (value: any) {
    this.value = value
    this.dep = new Dep()
    this.vmCount = 0
    def(value, '__ob__', this)
    if (Array.isArray(value)) {
      const augment = hasProto
        ? protoAugment
        : copyAugment
      augment(value, arrayMethods, arrayKeys)
      this.observeArray(value)
    } else {
      this.walk(value)
    }
  }
}

将对象的每个属性转换为settergetter的时候,又new了一个Dep

export function defineReactive (
  obj: Object,
  key: string,
  val: any,
  customSetter?: ?Function,
  shallow?: boolean
) {
 let childOb = !shallow && observe(val) // 如果是对象 创建自Observer
  const dep = new Dep() // #1 <---
  Object.defineProperty(obj,key,{
     //省略部分
    get: function reactiveGetter () {
      const value = getter ? getter.call(obj) : val
      if (Dep.target) {
        dep.depend()// 这里用的是 #1
        if (childOb) {
          childOb.dep.depend() //这里用的是子Observer实例的dep属性 #2
        }
        if (Array.isArray(value)) {
          dependArray(value)
        }
      }
      return value
    }
}
)

我的问题是:#1#2这两个Dep有什么区别?如果属性是个对象的话,这里是不是重复的依赖?

阅读 9.3k
1 个回答

你在Vue代码中全局搜一下dep.notify就差不多明白了。

一共有四个地方调用了dep.notify。

其中三个地方是调用了ob.dep.notify()。
分别是:
1.对数组push等七个方法重写的函数中
2.set方法,为一个对象添加一个属性
3.del方法,为对象删除一个属性

而闭包中的dep.notify()只是在Object.defineProperty的set方法中触发。

那么很清楚了,#1是闭包中的Dep,用于由对象本身修改而触发setter函数导致闭包中的Dep通知所有的Watcher对象。#2则是在对象本身增删属性或者数组变化的时候被触发的Dep。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏