从源码角度了解Vue生命周期
每個Vue應用都是通過new Vue()創建一個Vue實例開始。Vue()函數可以傳入選項Options,常見的有el、template和data選項等。
el 只在new創建實例時生效,其值可以是一個CSS選擇器或一個HTML Element實例。實例掛載后(mounted之后)可通過vm.$el訪問,如果開始實例化時不給el選項,則需要調用vm.$mount指定掛載點。掛載元素會被編譯后生成的DOM替換掉。
template定義組件的模板,即要渲染的內容。
data選項的值是對象類型,它的property會被Vue實例所代理,成為響應式數據,擁有雙向改變的特性。只有在創建時data中的屬性property才會被響應式化。
Vue()的具體實現如下:
import {initMixin} from './init'
function Vue(options){
//安全性檢查:是否為非生產環境且this是否是Vue的實例
//如果是非生產環境且this不是Vue的實例,即沒有通過使用new實例化Vue
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)
}
initMixin(Vue)
export default Vue
_init方法是整個初始化流程的開始。initMixin方法向Vue構造函數的原型prototype掛載一些方法,_init便是其中之一。
export function initMixin(Vue){
//在Vue的構造函數的原型上添加一個_init方法
Vue.prototype._init=function(options){
//合并構造函數的選項和用戶傳入的選項并掛載到Vue實例vm的$options選項上
vm.$options=mergeOptions(
resolveConstructorOptions(vm.constructor),
options||{},
vm
)
//依次初始化
initLifecycle(vm) //初始化組件的生命周期
initEvents(vm) //初始化事件
initRender(vm) //初始化渲染函數
callHook(vm,'beforeCreate') //調用beforeCreate生命周期鉤子函數
initInjections(vm) //初始化注入,處理inject選項
initState(vm) //初始化狀態,包括data、props、methods、computed、watch
initProvide(vm) //初始化provide,處理provide選項
callHook(vm,'created') //調用created生命周期鉤子函數
//如果有掛載的目標元素
if(vm.$options.el){
//掛載實例到目標元素上
vm.$mount(vm.$options.el)
}
}
}
每個Vue實例在創建時都要經過一系列過程:初始化、模板編譯、掛載、卸載這四個階段。階段之間會陸續執行一類函數,稱為生命周期函數。如下圖所示:
Vue生命周期圖

new Vue()到created的階段是初始化階段,該階段會初始化屬性props、事件events和響應式數據data,還有computed、watch、provide和inject。
created到beforeMount的階段是模板編譯階段,明顯運行時版本不包含該階段,只存在于完整版Vue中。運行時版本的Vue.js需要搭配其他___工具如vue-loader等來預編譯Vue模板。模板編譯即通過編譯器將模板代碼轉換成javascript代碼。
beforeMount到mounted階段是掛載階段,掛載階段也是Vue生命周期中占時最長的一個階段。掛載的意思是指Vue.js將其實例掛載到DOM元素上,也就是用編譯后的模板代碼替換指定DOM元素的內部內容,實現模板內容的渲染。同時,Vue.js會啟用Watcher來跟蹤依賴的變化。依賴是指初始化時被響應式化的數據。掛載階段的原理和vm.$mount方法息息相關。
在掛載階段,數據(狀態)發生變化后,Watcher會通知虛擬DOM重新渲染,新DOM將替換舊DOM,從beforeUpdate函數執行后到updated函數結束前是頁面重渲染階段。
最后的卸載階段,Vue調用vm.$destroy方法來銷毀自身。
總結
以上是生活随笔為你收集整理的从源码角度了解Vue生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。