vue3的ReativeEffect原理

  1. 执行setupRenderEffect
  2. 声明了componentUpdateFn
  3. 产生componentUpdateFn对应的副作用函数
  4. new ReactiveEffect(),产生了activeEffect 实例
  5. 第一次执行componentUpdateFn,本次内部走的是未挂载流程patch
  6. patch时候,activeEffect响应式数据双向收集依赖
  7. 当响应式数据发生变化时,触发关联的activeEffect执行effect.schedule
  8. schedule其实就是() => queueJob(instance.update)
  9. queueJobinstance.update放入队列queue中 ,且进一步执行queueFlush
  10. queueFlush建立了一个Promise微任务
  11. 等到执行微任务时候,就是批量执行instance.update
  12. 第二次执行componentUpdateFn,本次内部走的是挂载完成的patch
const effect = (instance.effect = new ReactiveEffect(
   componentUpdateFn,
   () => queueJob(instance.update), // 其实就是effect.run
   instance.scope
))
const update = ( instance.update = effect.run.bind(effect) ) // bind是返回run函数的,不是执行run函数
class ReactiveEffect{
  active = true
  deps: Dep[] = []
  parent: ReactiveEffect | undefined = undefined
  computed?: ComputedRefImpl<T>
  allowRecurse?: boolean
  onStop?: () => void
  onTrack?: (event: DebuggerEvent) => void
  onTrigger?: (event: DebuggerEvent) => void
  constructor(
    public fn: () => T,
    public scheduler: EffectScheduler | null = null,
    scope?: EffectScope
  ) {
    recordEffectScope(this, scope)
  }
  run() {
    if (!this.active) {
      return this.fn()
    }
    let parent: ReactiveEffect | undefined = activeEffect
    let lastShouldTrack = shouldTrack
    while (parent) {
      if (parent === this) {
        return
      }
      parent = parent.parent
    }
    try {
      this.parent = activeEffect
      activeEffect = this
      shouldTrack = true

      trackOpBit = 1 << ++effectTrackDepth

      if (effectTrackDepth <= maxMarkerBits) {
        initDepMarkers(this)
      } else {
        cleanupEffect(this)
      }
      return this.fn()
    } finally {
      if (effectTrackDepth <= maxMarkerBits) {
        finalizeDepMarkers(this)
      }
      trackOpBit = 1 << --effectTrackDepth
      activeEffect = this.parent
      shouldTrack = lastShouldTrack
      this.parent = undefined
    }
  }
  stop() {
    if (this.active) {
      cleanupEffect(this)
      if (this.onStop) {
        this.onStop()
      }
      this.active = false
    }
  }
}
function queueJob(job) {
  if (
    (!queue.length ||
      !queue.includes(
        job,
        isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex
      )) &&
    job !== currentPreFlushParentJob
  ) {
    if (job.id == null) {
      queue.push(job)
    } else {
      queue.splice(findInsertionIndex(job.id), 0, job)
    }
    queueFlush()
  }
}
function queueFlush() {
  if (!isFlushing && !isFlushPending) {
    isFlushPending = true
    currentFlushPromise = resolvedPromise.then(flushJobs)
  }
}
const resolvedPromise = Promise.resolve()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值