首先在new Vue之前就要初始化生命周期
Vue.Mixin({
created:function b(){
}
})
let vm=new Vue({
el:'#app',
data(){
return {
msg:'data',
msg2:'data2',
a:{b:200},
list:[1,2,{a:{b:3}}]
}
},
props:{},
watch:{},
})
这里的Mixin可以理解为将Vue原始的options和传入的子对象进行合并
Vue.Mixin=function (mixin){
//对象的合并
this.options=mergeOptions(this.options,mixin)
return this
}
export function mergeOptions(parent,child){
//Vue.options={created:[a,b,c], watch:[a,b]}
// console.log(parent,child)
const options={}
//如果有父亲没有儿子
for (let key in parent){
mergeField(key)
}
//儿子有父亲没有
for (let key in child){
mergeField(key)
}
function mergeField(key){
//根据key 策略模式
if (starts[key]){
options[key]=starts[key](parent[key], child[key])
}else{
options[key]=child[key]
}
}
return options
}
export const HOOKS=[
"beforeCreate",
"created",
"beforeMount",
"mounted",
"beforeUpdate",
"updated",
"beforeDestroy",
"destroyed"
]
//策略模式
let starts={}
starts.data=function(){}
starts.computed=function(){}
starts.watch=function(){}
starts.methods=function(){}
//遍历生命周期
HOOKS.forEach(hooks => {
starts[hooks]=mergeHook
});
function mergeHook(parentVal,childVal){
//Vue.options={created:[a,b,c], watch:[a,b]}
// console.log(parentVal,childVal)
if (childVal){
if(parentVal){
return parentVal.concat(childVal)
}else{
return [childVal]
}
}else{
return parentVal
}
}
之后初始化生命周期
vm.$options=mergeOptions(Vue.options,options)
callHook(vm,'beforeCreate')
//初始化状态
initState(vm)
callHook(vm,'create')
其中callHook为,可以执行生命周期里的函数
export function callHook(vm,hook){
const handlers=vm.$options[hook]
if (handlers){
for(let i=0;i<handlers.length;i++){
handlers[i].call(this)
}
}
}
//源码中
callHook(vm,"beforeMount")
vm._update(vm._render())
//1.vm._render将render函数变成虚拟dom vnode
//2.vm._update将vnode变成真实dom再放到页面上去
callHook(vm,"mounted")