官網對生命週期給出了一個比較完成的流程圖,以下所示:vue
從圖中咱們能夠看到咱們的Vue建立的過程要通過如下的鉤子函數:數組
beforeCreate => created => beforeMount => mounted => beforeUpdate => updated => beforeDestroy => destroyed
那麼咱們就從源碼的角度來看一看吧,當咱們new Vue的時候,會執行_init函數ide
function Vue (options) { if (process.env.NODE_ENV !== 'production' && !(this instanceof Vue) ) { warn('Vue is a constructor and should be called with the `new` keyword') } this._init(options) }
init函數以下函數
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) { .... 如下就是進行了生命週期 vm._self = vm // 首先進行初始化生命週期的參數 initLifecycle(vm) // 在初始化事件 initEvents(vm) // 初始化render initRender(vm) // 開始調用beforeCreate鉤子函數,和圖中的流程圖同樣 callHook(vm, 'beforeCreate') // 以後開始初始化變量等一些數據 initInjections(vm) // resolve injections before data/props initState(vm) initProvide(vm) // resolve provide after data/props // 開始調用created鉤子函數 callHook(vm, 'created') /* istanbul ignore if */ if (process.env.NODE_ENV !== 'production' && config.performance && mark) { vm._name = formatComponentName(vm, false) mark(endTag) measure(`vue ${vm._name} init`, startTag, endTag) } if (vm.$options.el) { vm.$mount(vm.$options.el) } } }
以上init函數咱們已經看到了beforeCreate和created,那麼callHook是怎麼調用的鉤子函數呢?this
export function callHook (vm: Component, hook: string) { // #7573 disable dep collection when invoking lifecycle hooks pushTarget() // 從$options裏拿到鉤子函數 const handlers = vm.$options[hook] if (handlers) { for (let i = 0, j = handlers.length; i < j; i++) { try { // 而後再調用 handlers[i].call(vm) } catch (e) { handleError(e, vm, `${hook} hook`) } } } if (vm._hasHookEvent) { vm.$emit('hook:' + hook) } popTarget() }
這邊就會有幾個問題:
從vm.$options[hook]中取鉤子函數,那個這個鉤子函數是哪來來的? 爲了拿到的鉤子函數是個數組?咱們平時使用不都是隻是寫個函數嗎?spa
咱們能夠看到在$options是在下面_init中進行合併的prototype
Vue.prototype._init = function(){ ... vm.$options = mergeOptions( resolveConstructorOptions(vm.constructor), options || {}, vm ) ... } export const LIFECYCLE_HOOKS = [ 'beforeCreate', 'created', 'beforeMount', 'mounted', 'beforeUpdate', 'updated', 'beforeDestroy', 'destroyed', 'activated', 'deactivated', 'errorCaptured' ]
咱們能夠看到鉤子函數一開始就已經在vue內部已經定義好了,而且還有幾個鉤子函數不是實話化實例的使用執行的。而是對keep-alive組件配合使用的activated,deactivated。以及錯誤拋出鉤子函數errorCaptured
而後再根據這些內部定義的鉤子函數和傳入的參數進行合併code
那麼爲何鉤子函數是數組呢?這個其實很簡單是由於vue內部也須要執行一些函數,顧把函數也放到鉤子函數裏。因此須要數組遍歷。orm
因此這些所謂的鉤子函數就是一個回調函數。生命週期
其他幾個鉤子函數也是在須要調用的時候使用callHook(vm, 'xxx')來執行
若是對您有幫助請點個贊,謝謝!