activated、deactivated发生的生命周期具体位置

keep-alive 缓存的组件会多两个生命周期activateddeactivated,缓存后的组件经常会用activated这个生命周期,那么这两个生命周期和vue的其他生命周期怎么排序执行的呢?

我们知道VUE的其他的生命周期是这样的:

image.png

activated 这个生命周期呢?

我们可以从源码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挂载后,回去判断当前组件是否vnode.data.keepAlive ,如果context._isMounted是true那么有可能keep-alive组件的子组件也许会改变,因此直接在此处行走树可能会在不正确的子组件上调用已激活的钩子。相反我们把它们推入队列,整个patch过程结束后将对其进行处理。

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)
    }
  }
}

上面代码是做队列处理。

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')
  }
}

上面是发起activated

deactivated那么是在什么时候调用的呢?

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的时候直接调用deactivateChildComponent,发起deactivated,不走$destroy

以上是VUE里面keep-alive中activated、deactivated两个点发生的生命周期位置,如果有误欢迎大家在评论里面指正。

你可能感兴趣的:(activated、deactivated发生的生命周期具体位置)