失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > actived生命周期_activated deactivated发生的生命周期具体位置

actived生命周期_activated deactivated发生的生命周期具体位置

时间:2019-11-18 09:19:37

相关推荐

actived生命周期_activated deactivated发生的生命周期具体位置

被 keep-alive 缓存的组件会多两个生命周期activated、deactivated,缓存后的组件经常会用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两个点发生的生命周期位置,如果有误欢迎大家在评论里面指正。

如果觉得《actived生命周期_activated deactivated发生的生命周期具体位置》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。