any-u / Start-From-Zero-Vue

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

响应式之Dep - 7

any-u opened this issue · comments

commented

响应式之Dep - 7

前言

前文中常常会出现Dep相关的属性,但究竟何为 Dep?本文让我们好好来分析分析.

Dep

// src/core/observer/dep.js
let uid = 0

export default class Dep {
  // 静态属性 target -> 当前观测的目标
  static target: ?Watcher;
  id: number; // 依赖id
  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 () {
    // 首先固定依赖数组
    const subs = this.subs.slice()
		
    // 遍历依赖数组,通知更新
    for (let i = 0, l = subs.length; i < l; i++) {
      subs[i].update()
    }
  }
}

这里逻辑其实很简单,添加订阅者(addSub)、移除依赖(removeSub)、收集依赖(depend)、通知更新(notify)

唯一的观察者

// 给 Dep 添加一个属性 target,用来确保唯一性
Dep.target = null
const targetStack = [] // 存储目标栈

export function pushTarget (target: ?Watcher) {
  // 目标栈新增模板
  targetStack.push(target)
  // 把当前的观察者改为target
  Dep.target = target
}

export function popTarget () {
  // 模板删除最后一个目标
  targetStack.pop()
  // 把当前的观察者改为上一个target
  Dep.target = targetStack[targetStack.length - 1]
}

除此这外,还有个问题,就是 Watcher 到底是什么,详见下文分析