相关信息
生命周期函数就是组件在初始化或者数据更新时会触发的钩子函数。
在初始化时,会调用以下代码,生命周期就是通过 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
钩子了。如果有子组件的话,会递归挂载子组件,只有当所有子组件全部挂载完毕,才会执行根组件的挂载钩子。
接下来是数据更新时会调用的钩子函数
function flushSchedulerQueue() { // ... for (index = 0; index < queue.length; index++) { watcher = queue[index] if (watcher.before) { watcher.before() // 调用 beforeUpdate } id = watcher.id has[id] = null watcher.run() // in dev build, check and stop circular updates. 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') } } }
上图还有两个生命周期没有说,分别为 activated
和 deactivated
,这两个钩子函数是 keep-alive
组件独有的。用 keep-alive
包裹的组件在切换时不会进行销毁,而是缓存到内存中并执行 deactivated
钩子函数,命中缓存渲染后会执行 actived
钩子函数。
最后就是销毁组件的钩子函数了
Vue.prototype.$destroy = function() { // ... callHook(vm, 'beforeDestroy') vm._isBeingDestroyed = true // remove self from parent const parent = vm.$parent if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) { remove(parent.$children, vm) } // teardown watchers if (vm._watcher) { vm._watcher.teardown() } let i = vm._watchers.length while (i--) { vm._watchers[i].teardown() } // remove reference from data ob // frozen object may not have observer. if (vm._data.__ob__) { vm._data.__ob__.vmCount-- } // call the last hook... vm._isDestroyed = true // invoke destroy hooks on current rendered tree vm.__patch__(vm._vnode, null) // fire destroyed hook callHook(vm, 'destroyed') // turn off all instance listeners. vm.$off() // remove __vue__ reference if (vm.$el) { vm.$el.__vue__ = null } // release circular reference (##6759) if (vm.$vnode) { vm.$vnode.parent = null } }
在执行销毁操作前会调用 beforeDestroy
钩子函数,然后进行一系列的销毁操作,如果有子组件的话,也会递归销毁子组件,所有子组件都销毁完毕后才会执行根组件的 destroyed
钩子函数。
本文作者:毛超颖
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!