vue生命周期详解

1,767 阅读3分钟

在说vue生命周期之前,先了解下vue是怎么执行的

渲染子组件的时候又会重新执行上面的这些过程

beforCreate和created

这两个生命周期是vue init的过程

所以这两个生命周期执行顺序,先父后子

beforeMounted和mounted

beforeMounted是在mount的开始执行的时候调用,渲染子组件的时候再执行beforeMounted,所以它的执行顺序,先父后子

mounted 是在patch完成之后执行。从流程图可以看出,vue组件的挂载是先子后父,所以mounted的执行顺序也是先子后父吗?理论执行顺序是这样的,但是子组件挂载的时候,由于根组件还没挂载到页面上,所以此时访问不到dom元素,也违背了mounted挂载完成的意思。

那什么时候执行呢?在子组件执行invokeInersetHook时有个判断

initial组件初始化时为ture,并且不是根vue实例时,就把vnode队列赋值给父组件的一个属性上,然后在父组件中把子组件的insertedVnodeQueue  push到父组件中,此时父组件中insertedVnodeQueue还未收集,在invokeCreateHooks时才完成父组件vnode的收集。所以这就保证了vnode队列的顺序,子组件vnode在父组件vnode的前面

最后在根vue实例patch结束dom元素渲染出来的时候,遍历insertedVnodeQueue队列,执行mounted钩子,最后根vue实例再执行自己的mounted钩子。

所以mounted执行顺序先子后父

beforeUpdate和updated

组件更新的时候,先更新父组件,然后通过传给子组件的props的变化,影响子组件的更新,所以beforeUpdate执行顺序,先父后子

updated:每个组件init的时候都生成一个watcher用于通知组件的变化,在render的过程会访问组件上的数据,从而完成收集watcher的过程。当数据变化的时候会通知数据依赖的watcher push到一个watcherQueue中,然后在一个异步的时机统一更新。所有的组件更新完成之后,让watcherQueue从队列尾向前调用updated(watcherQueue的添加顺序是先父后子,内部还做了sort排列让父组件在前)

所以updated执行顺序先子后父

beforeDestory和destoryed

beforeDestory:先父后子,先在父组件开始beforeDestory钩子,然后调用子组件的beforeDestory

destoryed:

先完成子组件的销毁,再执行destoryed钩子。

所以destoryed执行顺序先子后父

activated和deactivated

activated和mounted过程一样,是在根vue实例统一执行invokeInsertHook的时候,先执行完mounted钩子,在执行activatedChildComponent函数

在这个函数中递归调用子组件的activated的钩子

为什么和不和mounted钩子一样在遍历每个组件vnode时的执行钩子呢?因为,keepAlive组件的子组件中keepAlive属性为false,所以不会执行activated钩子,统一在keepAlive组件递归调用

所以activated执行顺序先子后父

deactivated:是通过递归访问子组件调用deactivated钩子,子组件deactivated完了再调用父组件的deactivated

所以activated执行顺序先子后父