vue生命周期分析

什么是生命周期

每一个vue实例从创建到销毁的过程,就是这个vue实例的生命周期。在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。那么这些过程中,具体vue做了些啥,话不多说先看图:

src=http___img-blog.csdnimg.cn_20200722163048799.png_x-oss-process=image_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1c2h1YWl3ZWkx,size_16,color_FFFFFF,t_70&refer=http___img-blog.csdnimg.webp

生命周期.png

开始

生命周期函数就是组件在初始化或者数据更新时会触发的钩子函数。在初始化时,会调用以下代码,生命周期就是通过 callHook 调用的

Vue.prototype._init = function (options) {
    initLifecycle(vm)
    initEvents(vm)
    initRender(vm)
    callHook(vm, 'beforeCreate') // 拿不到 props data
    initInjections(vm)
    initState(vm)
    initProvide(vm)
    callHook(vm, 'created')
} 

可以发现在以上代码中,beforeCreate 调用的时候,是获取不到 props 或者data 中的数据的,因为这些数据的初始化都在 initState 中。

接下来会执行挂载函数

export function mountComponent {
    callHook(vm, 'beforeMount')
 
    if (vm.$vnode == null) {
        vm._isMounted = true
        callHook(vm, 'mounted')
    }
} 

beforeMount 就是在挂载前执行的,然后开始创建 VDOM 并替换成真实 DOM,最后执行 mounted 钩子。这里会有个判断逻辑,如果是外部 new Vue({}) 的话,不会存在$vnode ,所以直接执行 mounted 钩子了。如果有子组件的话,会递归挂载子组件,只有当所有子组件全部挂载完毕,才会执行根组件的挂载钩子。

接下来是数据更新时会调用的钩子函数

for (index = 0; index < queue.length; index++) {
    watcher = queue[index]
    if (watcher.before) {
        watcher.before() // 调用 beforeUpdate
    }
    id = watcher.id
    has[id] = null
    watcher.run()
   
    if (process.env.NODE_ENV !== 'production' && has[id] != null) {
        circular[id] = (circular[id] || 0) + 1
        if (circular[id] > MAX_UPDATE_COUNT) {
            warn(
                'You may have an infinite update loop ' +
                (watcher.user
                    ? `in watcher with expression "${watcher.expression}"`
                    : `in a component render function.`),
                watcher.vm
            )
            break
        }
    }
}
callUpdatedHooks(updatedQueue)
   }
function callUpdatedHooks(queue) {
    let i = queue.length
    while (i--) {
        const watcher = queue[i]
        const vm = watcher.vm
        if (vm._watcher === watcher && vm._isMounted) {
            callHook(vm, 'updated')
        }
    }
} 

activateddeactivated,这两个钩子函数是 keep-alive 组件独有的。用 keep-alive 包裹的组件在切换时不会进行销毁,而是缓存到内存中并执行 deactivated 钩子函数,命中缓存渲染后会执行 actived 钩子函数。

最后就是销毁组件的钩子函数了

 Vue.prototype.$destroy = function () {
  
    callHook(vm, 'beforeDestroy')
    vm._isBeingDestroyed = true
   
    const parent = vm.$parent
    if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) {
        remove(parent.$children, vm)
    }
  
    if (vm._watcher) {
        vm._watcher.teardown()
    }
    let i = vm._watchers.length
    while (i--) {
        vm._watchers[i].teardown()
    }
   
    if (vm._data.__ob__) {
        vm._data.__ob__.vmCount--
    }
   
    vm._isDestroyed = true
  
  
    vm.__patch__(vm._vnode, null)
  
    callHook(vm, 'destroyed')
   
    vm.$off()
   
    if (vm.$el) {
        vm.$el.__vue__ = null
    }
   
    if (vm.$vnode) {
        vm.$vnode.parent = null
    }
} 

在执行销毁操作前会调用 beforeDestroy 钩子函数,然后进行一系列的销毁操作,如果有子组件的话,也会递归销毁子组件,所有子组件都销毁完毕后才会执行根组件的destroyed 钩子函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值