vue依赖包(vue依赖注入的三种方式)

Vue 依赖收集整体流程其实就是一套「订阅者模式」,收集订阅者,把所有需要监听内容数据,全都收集起来。

每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。 
https://cn.vuejs.org/v2/guide/reactivity.html#%E5%A6%82%E4%BD%95%E8%BF%BD%E8%B8%AA%E5%8F%98%E5%8C%96
之前文章写过 Vue 执行数据监听是重写了 Object.defineProperty 里 get 方法,通过 defineReactive 这个函数来实现数据的收集。
var dep = new Dep();
Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () {    // 获取当前监听的值 const value = getter ? getter.call(obj) : val;    // Dep 在上面已经声明;    // Dep.target 表明是当前哪个 Watcher if (Dep.target) {      dep.depend();// 添加到订阅列表里,方法在 dep.js 文件定义 if (childOb) { childOb.dep.depend() if (Array.isArray(value)) { dependArray(value) } } } return value }})
new Dep() 初始化 Dep 来收集 watcher ,简单来说 Dep 是个「订阅列表」。
get 方法里面:先获取当前值赋值给 value,Dep.target 是静态属性,表明我当前执行的 Watcher 是哪个。Dep 的相关文件定义在 src/core/observer/dep.js
export default class Dep {  static target: ?Watcher;// 静态属性  id: number;// Dep id  subs: Array<Watcher>;// 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)    }  }}
然后去执行 dep.depend() 方法把当前 watcher 添加到 Dep 订阅列表里。depend 方法是在 Dep 类里声明的,而这里的 Dep.target 表示的是当前的 watcher ,而 addDep 方法则是在 watcher 里面声明的,把 dep id 添加到 newDepIds 数组里。
Dep 原型上的方法 addSub 把 watcher 都添加到 subs 里面,每添加一个订阅者 id 都会加 1,用 removeSub 方法来删除 subs 里面对应的 watcher 。
Watcher 相关文件定义在 src/core/observer/watcher.js。
    export default class Watcher {  addDep (dep: Dep) {    const id = dep.id    if (!this.newDepIds.has(id)) {      this.newDepIds.add(id)      this.newDeps.push(dep)      if (!this.depIds.has(id)) {        dep.addSub(this)      }    }  },  get () {    pushTarget(this)  }}
    而 watcher 类实现的就是「订阅者」。
    Watcher 里调用的方法 get 里 pushTarget 方法其实是在 Dep 里面定义的,来把当前的 watcher 添加到 targetStack 栈中,popTarget 则是把 watcher 从 targetStack 中移除,通过这「添加」和「移除」给 Dep.target 来赋值当前 Watcher。
      const targetStack = []export function pushTarget (target: ?Watcher) {  targetStack.push(target)  Dep.target = target}export function popTarget () {  targetStack.pop()  Dep.target = targetStack[targetStack.length - 1]}

      依赖收集的目的为了把 Watcher 收集起来,等触发 getter 的时候,会通知需要更新的 watcher 去执行更新。


      图片授权基于 www.pixabay.com 相关协议

      推荐阅读

      如何用 vue-cli 调试源码?
      如何调试 Vue 源码?

      Vue 在挂载数据前都经历了什么?


      原创文章,作者:小道研究,如若转载,请注明出处:https://www.sudun.com/ask/34516.html

      (0)
      小道研究's avatar小道研究
      上一篇 2024年4月14日 上午8:09
      下一篇 2024年4月14日 上午8:11

      相关推荐

      • 租用服务器可以做什么?

        越来越多的企业会选择服务器的租用,它能够为客户提供高性能、高可用性和灵活性的服务,可以提供远程管理工具,方便管理员对应用程序进行监控和管理,同时可以实现多个应用

        2024年9月21日
        0
      • plc编程的t是什么

        PLC编程中的T是计时器的缩写。在编程中,定时器用于测量时间间隔并控制事件功能组件发生的延迟。在大多数PLC 编程环境中,定时器分为两类:ON延时计时器(TON)和关闭延迟定时器(…

        网站运维 2024年5月12日
        0
      • 我家里有100M宽带,为什么网速还是这么慢?

        随着现在网络的不断发展,100M的宽带基本上成为了家庭宽带的标配,100M的宽带,很多人看到这个数字觉得网络的速度应该很快了,但是实际用起来为什么有些人觉得慢呢

        2024年8月29日
        0
      • 泛在计算安全综述

        泛在计算安全综述摘 要 随着人机物互联融合的泛在计算及其关键技术的快速发展,泛在计算已成为我国智能软硬件创新研发和生态构建的研究热点,驱动了智慧家庭、工业互联网、自动驾驶、智能云计算等众多典型应用产业日益普及繁荣,其安全问题也受到越来越多研

        网站运维 2024年7月4日
        0

      发表回复

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