带你阅读Vue3.0响应式系统源码4-依赖绑定以及触发依赖的执行策略

本文深入探讨Vue3.0响应式系统的依赖绑定和触发依赖的执行策略,包括代理对象与effect的绑定、effect的触发流程,以及不同观察者的执行策略。通过分析源码,揭示了Vue3.0如何确保数据更新后的正确视图同步。
摘要由CSDN通过智能技术生成

主题:依赖绑定以及触发依赖的执行策略

ps:多代码预警,本节因为涉及到的流程重要代码比较多,所以贴出了核心代码。

1.代理对象和影响因子effect如何绑定?(track)

​ 上一篇文章讲的是响应型数据的诞生。而前面说过,响应数据的诞生和它绑定观察者是两回事。那么响应型对象和影响因子effect是如何进行绑定依赖的呢?依赖的添加是在track方法中,下面来进行讲解:

  1. 什么时候进行调用track方法?

可以看到基本上都在handlers中进行调用,笔者对这些调用的方法进行追踪,发现调用者都在这里:

  • baseHandlers.tsgethasownKeys代理拦截方法里面进行追踪。
  • collectionHandlers.tsgethassizeforEachiterator方法里面进行追踪。
  • ref.ts:在value方法中,也就是求值方法。

所以可以验证其那面的一句话:在获取数据的地方进行依赖的绑定

  1. track方法中做了什么事情呢?下面我们会对整个流程所有必要代码进行解释,前面说过不会是以所有代码来进行讲解,只会讲解关键代码。

    /**
     * @description 追踪就是依赖的添加过程,相当于2.0的observer过程
     * @param target 代理对象
     * @param type 观察的类型,在开发环境中使用
     * @param key 想要被观察的属性,也就是effect函数中访问的对象的属性
     */
    export function track(target: object, type: TrackOpTypes, key: unknown) {
      // 如果不是在观察依赖添加时期或者当前没有活跃的effect的时候,不进行任何处理
      if (!shouldTrack || activeEffect === undefined) {
        return
      }
      // 接下来是进行构建targetMap的过程,详情可以查看附录2
      let depsMap = targetMap.get(target)
      if (depsMap === void 0) {
        targetMap.set(target, (depsMap = new Map()))
      }
      let dep = depsMap.get(key)
      if (dep === void 0) {
        depsMap.set(key, (dep = new Set()))
      }
    
      // 进行响应数据和effect的互相绑定,dep是一个Set数据结构,这个是进行去重操作
      if (!dep.has(activeEffect)) {
        dep.add(activeEffect)
        activeEffect.deps.push(dep)
        if (__DEV__ && activeEffect.options.onTrack) {
          activeEffect.options.onTrack({
            effect: activeEffect,
            target,
            type,
            key
          })
        }
      }
    }
    

    看完上面代码,我们会想要知道shouldTrackactiveEffect到底在什么时候进行:

    • shouldTrack:使用pauseTrackresumeTrack进行修改shouldTrack,而这两个方法在哪里进行调用呢?

      if (target.isUnmounted) {
          return
        }
        // disable tracking inside all lifecycle hooks
        // since they can potentially be called inside effects.
        pauseTracking()       // 退出观测模式模式
        // Set currentInstance during hook invocation.
        // This assumes the hook does not synchronously trigger other hooks, which
        // can only be false when the user does something really funky.
        setCurrentInstance(target)
        const res = callWithAsyncErrorHandling(hook, target, type, args)
        setCurrentInstance(null)
        resumeTracking()			// 进入观测模式
        return res
      })
      

      我们可以从代码和注释中了解到,在除了Unmounted生命周期钩子之外,在其他声明周期钩子函数调用期间不进行追踪操作。

    • activeEffect:在执行effect函数之前,会进行effect赋值给activeEffecteffect是一个带有属性的方法实例),在执行期间会进行依赖的绑定。

      function run(effect: ReactiveE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值