Vue源码学习4-响应式原理-Dep

  • 内容
  • 评论
  • 相关

前言

这篇文章就简单介绍一下Dep这个class,无需细看

--以下所有代码来自Vue 2.6.11 版本

贴源码

Dep 是在这个文件中定义的  src/core/observer/dep.js  ,代码不多。

Dep是干嘛的?它是用来和 Watcher 配合使用的,对 data props 做数据监测,data/props中的每一个字段都会被绑定一个Dep对象,无论是 基本数据 类型还是 Object 这样的引用数据类型,都会绑定,这一切都发生在 defineReactive 方法中。

1:找到其中的 target 这个静态变量,它非常重要,它指向的是一个Watcher对象,new Watcher 得到的对象。

defineReactive 的源码中,能在 Object.defineProperty 那段逻辑中找到 Dep.target 的使用,一个简单的判断,这里是 依赖收集 的关键点,这里暂时不深究了,记住这段逻辑就行了

2:找到其中一个名叫 targetStack 的数组,它也非常重要,虽然它是个数组,但他所有的操作都是按照 这种数据结构的操作规范来的

(栈是什么东西?贴一张别人的图,其余的细节,自行查阅啦)

不同的Watcher对象 在new Vue 的过程中会按照 的运行规律,不停的 压栈 出栈

压栈出栈使用的方法就是 pushTarget 和 popTarget,可以看到 压栈  pushTarget 的入参就是 Watcher 对象

3:其余的方法现在提了也没啥用,需结合 依赖收集派发更新 操作才能了解这些方法的作用

import type Watcher from './watcher'
import { remove } from '../util/index'
import config from '../config'

let uid = 0
export default class Dep {
  static target: ?Watcher;
  id: number;
  subs: Array<Watcher>;

  constructor () {
    this.id = uid++
    this.subs = []
  }

  addSub (sub: Watcher) {
    this.subs.push(sub)
  }

  removeSub (sub: Watcher) {
    remove(this.subs, sub)
  }

  depend () {
    if (Dep.target) {
      Dep.target.addDep(this)
    }
  }

  notify () {
    // stabilize the subscriber list first
    const subs = this.subs.slice()
    if (process.env.NODE_ENV !== 'production' && !config.async) {
      subs.sort((a, b) => a.id - b.id)
    }
    for (let i = 0, l = subs.length; i < l; i++) {
      subs[i].update()
    }
  }
}
Dep.target = null
const targetStack = []

export function pushTarget (target: ?Watcher) {
  targetStack.push(target)
  Dep.target = target
}

export function popTarget () {
  targetStack.pop()
  Dep.target = targetStack[targetStack.length - 1]
}

总结

这里就不总结了,简单的介绍而已

评论

0条评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注