我们在做项目时,通常会在组件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这些属性,也就是数据的初始化。