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 是无法正常完成逻辑执行的。


目录
相关文章
|
2天前
|
JavaScript 前端开发
深入了解前端框架Vue.js的响应式原理
本文将深入探讨Vue.js前端框架的核心特性之一——响应式原理。通过分析Vue.js中的数据绑定、依赖追踪和虚拟DOM等机制,读者将对Vue.js的响应式系统有更深入的理解,从而能够更好地利用Vue.js构建灵活、高效的前端应用。
|
2天前
|
JavaScript 测试技术 开发者
Vue 3 Vuex:构建更强大的状态管理系统
Vue 3 Vuex:构建更强大的状态管理系统
23 1
|
2天前
|
JavaScript 前端开发 开发者
Vue的响应式原理:深入探索Vue的响应式系统与依赖追踪
【4月更文挑战第24天】Vue的响应式原理通过JavaScript getter/setter实现,当数据变化时自动更新视图。它创建Watcher对象收集依赖,并通过依赖追踪机制精确通知更新。当属性改变,setter触发更新相关Watcher,重新执行操作以反映数据最新状态。Vue的响应式系统结合依赖追踪,有效提高性能,简化复杂应用的开发,但对某些复杂数据结构需额外处理。
|
2天前
|
JavaScript 前端开发 UED
Vue工具和生态系统: Vue.js和服务器端渲染(SSR)有关系吗?请解释。
Vue.js是一个渐进式JavaScript框架,常用于开发单页面应用,但其首屏加载较慢影响用户体验和SEO。为解决此问题,Vue.js支持服务器端渲染(SSR),在服务器预生成HTML,加快首屏速度。Vue.js的SSR可手动实现或借助如Nuxt.js的第三方库简化流程。Nuxt.js是基于Vue.js的服务器端渲染框架,整合核心库并提供额外功能,帮助构建高效的应用,改善用户体验。
21 0
|
2天前
|
JavaScript 搜索推荐 前端开发
Vue工具和生态系统:Vue CLI是什么?它的作用是什么?
【4月更文挑战第17天】Vue CLI是官方的Vue.js开发加速器,它包含交互式项目模板和@vue/cli-service,基于webpack并预设配置。支持个性化配置和插件扩展,拥有大量官方插件,整合最佳前端工具。还提供图形化界面用于项目管理和创建。
11 0
|
2天前
|
Web App开发 JavaScript 开发者
Vue工具和生态系统:什么是Vue DevTools?如何使用它?
Vue Devtools是Vue.js官方的浏览器扩展,用于简化应用调试和优化。可在Chrome和Firefox等浏览器上安装,集成到开发者工具中。安装步骤包括下载源码、npm安装、修改manifest.json并加载编译后的扩展。启用后,开发者能查看Vue组件树,检查属性,并在允许的情况下编辑data,提升开发效率。
18 0
|
2天前
|
JavaScript 前端开发 开发者
浅谈Vue 3的响应式对象: ref和reactive
浅谈Vue 3的响应式对象: ref和reactive
|
2天前
Vue3 响应式数据 reactive使用
Vue3 响应式数据 reactive使用
|
2天前
|
JavaScript
Vue 响应式数据的判断
Vue 响应式数据的判断
|
2天前
|
JavaScript
Vue 将响应式数据转为普通对象
Vue 将响应式数据转为普通对象