Vue 2 阅读理解(十七)之响应式系统(三)Dep 依赖收集

简介: Vue 2 阅读理解(十七)之响应式系统(三)Dep 依赖收集

响应式系统(三)


上一节 响应式系统(二) 中大致说明了 Observerobserve 通过 Object.defineProperty 实现数据响应式处理的过程,该过程也常称为 “数据劫持”。那么在数据的更新与读取过程都被劫持之后,就该处理 dom 与数据的依赖关系了,所以这一节我们简单学习一下 Dep 依赖收集


1. Dep


Dep,应该就是 dependence 的简写,表示依赖关系;并且肯定具有两个属性:依赖订阅者(观察者 watcher)数组与被依赖者。


Vue 2 中的 Dep 构造函数定义如下:


export interface DepTarget {
  id: number
  addDep(dep: Dep): void
  update(): void
}
export default class Dep {
  static target?: DepTarget | null
  id: number
  subs: Array<DepTarget>
  constructor() {
    this.id = uid++
    this.subs = []
  }
  addSub(sub: DepTarget) {
    this.subs.push(sub)
  }
  removeSub(sub: DepTarget) {
    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()
    }
  }
}


上面省略了开发环境中的 debug 处理部分;并且在开发环境下还可以在 notify 中选择同步按顺序执行。


整个 Dep 类的定义比较简单:


  1. 接收一个类静态属性 target,用来标记后面的订阅者依赖的数据。并且这里采用的是静态属性,而非每个 Dep 实例独有的属性,也是为了保证当前依赖订阅者在处理时不会被其他方式改变造成异常;并且该 target 对象必须包含两个方法:


  • addDep:将当前依赖添加到订阅者的依赖数组中


  • update:数据改变时触发的回调函数


  1. addSub 与 removeSub:用来管理该依赖的订阅者数组


  1. depend:在定义了 Dep.target 之后,将该依赖添加到依赖订阅者的依赖数组中


  1. notify:在当前数据改变时触发所有依赖订阅者的更新操作


当然,此时还需要一个修改 Dep.target 的方法


2. Dep.target


Dep.target = null
const targetStack: Array<DepTarget | null | undefined> = []
export function pushTarget(target?: DepTarget | null) {
  targetStack.push(target)
  Dep.target = target
}
export function popTarget() {
  targetStack.pop()
  Dep.target = targetStack[targetStack.length - 1]
}


这里默认 Dep.target 是一个空值,并且定义了一个变量 targetStack,根据命名来判断,是用来保存历史的 Dep.target 并可以回退以前目标对象的栈。


📌个人理解这里为什么会用一个数组和两个方法来处理当前订阅对象 Dep.target

因为在处理生命周期钩子函数 callHook,初始化 data 数据,触发 watch 回调函数的时候,为了避免内部数据改变导致依赖对应的数据的依赖订阅者(观察者)重复更新,导致数据和回调函数重复更新与执行,所以在以上几个阶段都会停止依赖收集。

而通过 Stack 和两个方法,可以简单通过处理开始前调用 pushTarget() 来停止依赖收集,并在结束后调用 popTarget() 来恢复原有的依赖引用。


🚀🚀🚀 Dep 在设计上都依赖 依赖订阅者(观察者)来实现完整的依赖订阅逻辑,脱离 Watcher 之后 Dep 是无法正常完成逻辑执行的。


目录
相关文章
|
20天前
|
API
vue3知识点:响应式数据的判断
vue3知识点:响应式数据的判断
25 3
|
23天前
|
缓存 JavaScript UED
优化Vue的响应式性能
【10月更文挑战第13天】优化 Vue 的响应式性能是一个持续的过程,需要不断地探索和实践,以适应不断变化的应用需求和性能挑战。
29 2
|
28天前
|
JavaScript 前端开发
Vue 2 和 Vue 3 之间响应式区别
10月更文挑战第7天
32 2
|
28天前
|
JavaScript 前端开发 API
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
526 0
|
1月前
|
JavaScript 前端开发 网络架构
如何使用Vue.js构建响应式Web应用
【10月更文挑战第9天】如何使用Vue.js构建响应式Web应用
|
1月前
|
JavaScript 前端开发
如何使用Vue.js构建响应式Web应用程序
【10月更文挑战第9天】如何使用Vue.js构建响应式Web应用程序
|
1月前
|
JavaScript 前端开发 数据安全/隐私保护
前端技术分享:使用Vue.js构建响应式表单
【10月更文挑战第1天】前端技术分享:使用Vue.js构建响应式表单
|
1月前
|
人工智能 监控 JavaScript
模拟依赖关系和 AI 是Vue.js测试的下一个前沿领域
模拟依赖关系和 AI 是Vue.js测试的下一个前沿领域
27 1
|
1月前
|
JSON JavaScript 前端开发
vue尚品汇商城项目-day00【项目介绍:此项目是基于vue2的前台电商项目和后台管理系统】
vue尚品汇商城项目-day00【项目介绍:此项目是基于vue2的前台电商项目和后台管理系统】
44 1
|
19天前
|
JavaScript 前端开发 API
vue3知识点:Vue3.0中的响应式原理和 vue2.x的响应式
vue3知识点:Vue3.0中的响应式原理和 vue2.x的响应式
23 0