我們在做項目時,通常會在組件created()鉤子函數中請求後端接口,得到數據後渲染視圖,這樣可以達到切換到對應頁面,即可顯示後端數據。
問題: vue生命週期created()前做了什麼?
我們可以看到,官網上給出的是,created()之前執行了初始化注入、初始化化校驗。
從vue2源碼看看:
路徑:\vue-dev\src\core\instance\init.js
export function initMixin (Vue: Class<Component>) {
Vue.prototype._init = function (options?: Object) {
const vm: Component = this //vue實例
...省略
// expose real self
vm._self = vm
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
...省略
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}
我們可以看到,在beforeCreate與created之間,調用了initInjections、initState、initProvide三個函數。在這之前要了解provide/inject是什麼
1.initInjections作用
代碼:\vue-dev\src\core\instance\inject.js
export function initInjections (vm: Component) {
// 遍歷inject的key從父/祖父組件中把provide的值捕捉下來
const result = resolveInject(vm.$options.inject, vm)
if (result) {
toggleObserving(false)
Object.keys(result).forEach(key => {
/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
defineReactive(vm, key, result[key], () => {
warn(
`Avoid mutating an injected value directly since the changes will be ` +
`overwritten whenever the provided component re-renders. ` +
`injection being mutated: "${key}"`,
vm
)
})
} else {
defineReactive(vm, key, result[key])
}
})
toggleObserving(true)
}
}
可以看出,initInjections是將inject轉換成對象,並遍歷這個對象,從vm._provided中找到對應的值。
2.initState作用
路徑:\vue-dev\src\core\instance\state.js
export function initState (vm: Component) {
vm._watchers = []
const opts = vm.$options
if (opts.props) initProps(vm, opts.props)
if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) {
initData(vm)
} else {
observe(vm._data = {}, true /* asRootData */)
}
if (opts.computed) initComputed(vm, opts.computed)
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch)
}
}
可以看出來initState()是初始化props、methods、data、computed、watch 參數
3.initProvide 作用
代碼:\vue-dev\src\core\instance\inject.js
export function initProvide (vm: Component) {
const provide = vm.$options.provide
if (provide) {
vm._provided = typeof provide === 'function'
? provide.call(vm)
: provide
}
}
可以看出,initProvide()就是將當前實例的provide的對象賦值vm._provided
所以從beforeCreate到created之間,vue初始化了inject/provide、props、methods、data、computed、watch這些屬性,也就是數據的初始化。