这一节主要记录一下:Vue
的初始化过程
以下正式开始:
Vue官网的生命周期图示表
[外链图片转存失败(img-LD0xeILd-1566566311651)(https://raw.githubusercontent.com/shisanOnly/blogImage/master/lifecycle.png)]
重点说一下 new Vue()
后的初始化阶段,也就是created
之前发生了什么。
[外链图片转存失败(img-etwifMzZ-1566566311652)(https://github.com/shisanOnly/blogImage/blob/master/initialization.jpg?raw=true)]
initLifecycle
阶段
export function initLifecycle (vm: Component) {
const options = vm.$options
// locate first non-abstract parent
let parent = options.parent
if (parent && !options.abstract) {
while (parent.$options.abstract && parent.$parent) {
parent = parent.$parent
}
parent.$children.push(vm) // 自己把自己添加到父级的$children数组中
}
vm.$parent = parent // 父组件实例
vm.$root = parent ? parent.$root : vm // 根组件 如果不存在父组件,则本身就是根组件
vm.$children = [] // 用来存放子组件
vm.$refs = {}
vm._watcher = null
vm._inactive = null
vm._directInactive = false
vm._isMounted = false
vm._isDestroyed = false
vm._isBeingDestroyed = false
}
接下来是initEvents
阶段
// v-on如果写在平台标签上如:div,则会将v-on上注册的事件注册到浏览器事件中
// v-on如果写在组件标签上,则会将v-on注册的事件注册到子组件的事件系统
// 子组件(Vue实例)在初始化的时候,有可能接收到父组件向子组件注册的事件。
// 子组件(Vue实例)自身模板注册的事件,只要在渲染的时候才会根据虚拟DOM的对比结果
// 来确定是注册事件还是解绑事件
// 这里初始化的事件是指父组件在模板中使用v-on注册的事件添加到子组件的事件系统也就是vue的事件系统。
export function initEvents (vm: Component) {
vm._events = Object.create(null) // 初始化
vm._hasHookEvent = false
// init parent attached events 初初始化腹肌组件添加的事件
const listeners = vm.$options._parentListeners
if (listeners) {
updateComponentListeners(vm, listeners)
}
}
export function updateComponentListeners (
vm: Component,
listeners: Object,
oldListeners: ?Object
) {
target = vm
updateListeners(listeners, oldListeners || {}, add, remove, createOnceHandler, vm)
target = undefined
}
initjections
阶段
export function initInjections (vm: Component) {
// 自下而上读取inject
const result = resolveInject(vm.$options.inject, vm)
if (result) {
// 设置为false 避免defineReactive函数把数据转换为响应式
toggleObserving(false)
Object.keys(result).forEach(key => {
defineReactive(vm, key, result[key])
})
// 再次更改回来
toggleObserving(true)
}
}
export function resolveInject (inject: any, vm: Component): ?Object {
if (inject) {
// inject is :any because flow is not smart enough to figure out cached
const result = Object.create(null)
// 如果浏览器支持Symbol,则使用Reflect.ownkyes(),否则使用Object.keys()
const keys = hasSymb