先看下這5個函數調用:vue
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')複製代碼
先看看callHook函數做用:調用生命週期鉤子函數數組
下面是
callHook
函數源碼
export function callHook (vm: Component, hook: string) {
// #7573 disable dep collection when invoking lifecycle hooks
pushTarget() //爲了不在某些生命週期鉤子中使用 props 數據致使收集冗餘的依賴
const handlers = vm.$options[hook] //獲取生命週期鉤子 vue選項合併會把生命週期鉤子選項合併成一個數組
if (handlers) {
for (let i = 0, j = handlers.length; i < j; i++) {
try {
handlers[i].call(vm)//爲了保證生命週期鉤子函數內能夠經過 this 訪問實例對象,因此使用 .call(vm) 執行這些函數
} catch (e) { //爲了捕捉可能出現的錯誤
handleError(e, vm, `${hook} hook`)
}
}
}
if (vm._hasHookEvent) {
vm.$emit('hook:' + hook)
}
popTarget() //爲了不在某些生命週期鉤子中使用 props 數據致使收集冗餘的依賴
}複製代碼
接收兩個參數:實例對象和要調用的生命週期鉤子的名稱bash
如今你們應該知道,beforeCreate
以及 created
這兩個生命週期鉤子的調用時機了。ide
其中 initState
包括了:initProps
、initMethods
、initData
、initComputed
以及 initWatch
。函數
因此當 beforeCreate
鉤子被調用時,全部與 props
、methods
、data
、computed
以及 watch
相關的內容都不能使用,固然了 inject/provide
也是不可用的。
ui
created
生命週期鉤子this
initInjections
、initState
以及 initProvide
執行完畢以後才被調用,spa
因此在 created
鉤子中,是徹底可以使用以上提到的內容的。但因爲此時尚未任何掛載的操做,可是在 created
中是不能訪問DOM的,即不能訪問 $el
。設計
callHook
函數最後一段代碼
code
if (vm._hasHookEvent) {
vm.$emit('hook:' + hook)
}複製代碼
vm._hasHookEvent
是在 initEvents
函數中定義的,它的做用是判斷是否存在生命週期鉤子的事件偵聽器,初始化值爲 false
表明沒有,當組件檢測到存在生命週期鉤子的事件偵聽器時,會將 vm._hasHookEvent
設置爲 true
介紹下生命週期鉤子事件幀聽器:
<child
@hook:beforeCreate="handleChildBeforeCreate"
@hook:created="handleChildCreated"
@hook:mounted="handleChildMounted"
@hook:生命週期鉤子
/>複製代碼
使用hook:加上生命週期鉤子名稱來監聽組件內對應的生命週期事件
接下來繼續講那幾個調用函數:initState
initState執行前先執行了initInjections函數,也就是說inject選項更早被初始化,因爲初始化inject設計到比較多 先跳過講initstate
export function initState (vm: Component) {
vm._watchers = [] //在vue實例對象上添加一個屬性(數組)
const opts = vm.$options //定義一個常量做爲vm.$options引用
if (opts.props) initProps(vm, opts.props) //判斷選項中是否有props 有則調用initprops
//判斷是否有methods,有則調用initmethodds初始化methods選項 if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) {//判斷data是否存在 //調用initdata初始化data選項
initData(vm)
} else {//若是不存在則調用observe函數觀察一個空對象
observe(vm._data = {}, true /* asRootData */)
}
if (opts.computed) initComputed(vm, opts.computed) //判斷computed是否存在,而後初始化
if (opts.watch && opts.watch !== nativeWatch) { //判斷是否存在和是不是原生對象...
initWatch(vm, opts.watch)
}
}複製代碼
整理完initstate函數發現都是一些初始化選項彙總: