activated、deactivated發(fā)生的生命周期具體位置

keep-alive 緩存的組件會(huì)多兩個(gè)生命周期activated、deactivated,緩存后的組件經(jīng)常會(huì)用activated這個(gè)生命周期,那么這兩個(gè)生命周期和vue的其他生命周期怎么排序執(zhí)行的呢?

我們知道VUE的其他的生命周期是這樣的:

image.png

activated 這個(gè)生命周期呢?

我們可以從源碼src/core/vdom/create-component.js看到:

insert (vnode: MountedComponentVNode) {
    const { context, componentInstance } = vnode
    if (!componentInstance._isMounted) {
      componentInstance._isMounted = true
      callHook(componentInstance, 'mounted')
    }
    if (vnode.data.keepAlive) {
      if (context._isMounted) {
        // vue-router#1212
        // During updates, a kept-alive component's child components may
        // change, so directly walking the tree here may call activated hooks
        // on incorrect children. Instead we push them into a queue which will
        // be processed after the whole patch process ended.
        queueActivatedComponent(componentInstance)
      } else {
        activateChildComponent(componentInstance, true /* direct */)
      }
    }
  }

從上面源碼可以看到,組件的mounted掛載后,回去判斷當(dāng)前組件是否vnode.data.keepAlive ,如果context._isMounted是true那么有可能keep-alive組件的子組件也許會(huì)改變,因此直接在此處行走樹(shù)可能會(huì)在不正確的子組件上調(diào)用已激活的鉤子。相反我們把它們推入隊(duì)列,整個(gè)patch過(guò)程結(jié)束后將對(duì)其進(jìn)行處理。

src/core/observer/scheduler.js

/**
 * Queue a kept-alive component that was activated during the patch.
 * The queue will be processed after the entire tree has been patched.
 */
export function queueActivatedComponent (vm: Component) {
  // setting _inactive to false here so that a render function can
  // rely on checking whether it's in an inactive tree (e.g. router-view)
  vm._inactive = false
  activatedChildren.push(vm)
}

...
...
/**
 * Push a watcher into the watcher queue.
 * Jobs with duplicate IDs will be skipped unless it's
 * pushed when the queue is being flushed.
 */
export function queueWatcher (watcher: Watcher) {
  const id = watcher.id
  if (has[id] == null) {
    has[id] = true
    if (!flushing) {
      queue.push(watcher)
    } else {
      // if already flushing, splice the watcher based on its id
      // if already past its id, it will be run next immediately.
      let i = queue.length - 1
      while (i > index && queue[i].id > watcher.id) {
        i--
      }
      queue.splice(i + 1, 0, watcher)
    }
    // queue the flush
    if (!waiting) {
      waiting = true

      if (process.env.NODE_ENV !== 'production' && !config.async) {
        flushSchedulerQueue()
        return
      }
      nextTick(flushSchedulerQueue)
    }
  }
}

上面代碼是做隊(duì)列處理。

src/core/instance/lifecycle.js


export function activateChildComponent (vm: Component, direct?: boolean) {
  if (direct) {
    vm._directInactive = false
    if (isInInactiveTree(vm)) {
      return
    }
  } else if (vm._directInactive) {
    return
  }
  if (vm._inactive || vm._inactive === null) {
    vm._inactive = false
    for (let i = 0; i < vm.$children.length; i++) {
      activateChildComponent(vm.$children[i])
    }
    callHook(vm, 'activated')
  }
}

上面是發(fā)起activated

deactivated那么是在什么時(shí)候調(diào)用的呢?

src/core/instance/lifecycle.js

export function deactivateChildComponent (vm: Component, direct?: boolean) {
  if (direct) {
    vm._directInactive = true
    if (isInInactiveTree(vm)) {
      return
    }
  }
  if (!vm._inactive) {
    vm._inactive = true
    for (let i = 0; i < vm.$children.length; i++) {
      deactivateChildComponent(vm.$children[i])
    }
    callHook(vm, 'deactivated')
  }
}

src/core/vdom/create-component.js

destroy (vnode: MountedComponentVNode) {
    const { componentInstance } = vnode
    if (!componentInstance._isDestroyed) {
      if (!vnode.data.keepAlive) {
        componentInstance.$destroy()
      } else {
        deactivateChildComponent(componentInstance, true /* direct */)
      }
    }
  }

組件是vnode.data.keepAlive的時(shí)候直接調(diào)用deactivateChildComponent,發(fā)起deactivated,不走$destroy。

以上是VUE里面keep-alive中activated、deactivated兩個(gè)點(diǎn)發(fā)生的生命周期位置,如果有誤歡迎大家在評(píng)論里面指正。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容