Vue2的源码学习3:mixin 原理的实现以及生命周期的调用
开始
前两节我们分别对Vue2中的响应式数据原理以及模板编译分别进行了总结整理,下面对Vue的mixin的实现和Vue的生命周期合并于调用进行总结整理。
Vue.mixin
Vue.mixin
Vue中的mixin的方法也是开发中一个很常用的方法,特别是在组件封装中,我们可以依赖它实现方法的复用,之前在总结Vuex的源码的时候,在实现全局安装Vuex的方法,同样也依赖它实现的。
juejin.im/post/5efdd3…
Vue.mixin({beforeCreate(){
//说明是根
if(this.$options && this.$options.store)
{
this.$store=this.$options.store;
}
else{
this.$store=this.$parent && this.$parent.$store;
}
}
})
实现
####思路
mixin 的本质还是对象之间的合并,但是对不同对象和方法右不同的处理方式,对于普通对象,就是简单的对象合并类似于Object.assign,对于基础类型就是后面的覆盖前面的,而对于生命周期上的方法,相同的则是合并到一个数组中,调用的时候依次调用。
####代码实现
- 定义mixin 方法
import { mergeOptions} from "./util/index.js";/*
初始化全局的API
*/
exportfunction initGlobalApi(Vue){
Vue.options={};
Vue.mixin=function(mixin){
this.options=mergeOptions(this.options,mixin);
return this;
}
}
- 合并对象的方法
exportfunction mergeOptions(parent,child){const options={} ;
for(let key in parent)
{
mergeFields(key)
}
for(let key in child)
{
if(!parent.hasOwnProperty[key]){
mergeFields(key)
}
}
/**
* 合并属性
* @param {*} key
*/
function mergeFields(key){
//如果策略模式上存在
if(strats[key]){
options[key]=strats[key](parent[key],child[key])
}
//如果都是对象 {a:11,b:2},{a:12,c:14} =>{a:12,b:2,c:14}
elseif(isReallyObject(parent[key]) && isReallyObject(child[key] ))
{
options[key]={
...parent[key],
...child[key]
}
}
elseif(child[key]){
options[key]=child[key]
}
else{
options[key]=parent[key];
}
}
return options;
}
其实源码中合并的方法很复杂,包括对合并对象的响应式数据处理,还有组件中 minins的合并策略,如有兴趣,可查看源码中的options.js 文件。
生命周期
生命周期的合并
Vue2 中有如下几个生命周期
'beforeCreate','created',
'beforeMount',
'mounted',
'beforeUpdate',
'updated',
'beforeDestroy',
'destroyed',
每个组件都有自己的生命周期,组件之间生命周期的合并也是依赖Vue.mixin 实现的
合并方法
//存放策略(合并对象前会优先调用)let strats={
}
const LIFECYCLE_HOOKS =[
'beforeCreate',
'created',
'beforeMount',
'mounted',
'beforeUpdate',
'updated',
'beforeDestroy',
'destroyed',
]
LIFECYCLE_HOOKS.forEach((hook)=>{
strats[hook]=mergeHook;
})
/**
* 合并生命周期的钩子
* @param {*} parentValue
* @param {*} childValue
*/
function mergeHook(parentValue,childValue){
//有子
if(childValue){
//有父
if(parentValue)
{
//合并
return parentValue.concat(childValue);
}
else{
//返回
return [childValue];
}
}
else{
return parentValue;
}
}
生命周期的调用
调用方法
exportfunction callHook(vm,hook){const hookCallbacks=vm.$options[hook] ||[];
for(let i=0;i<hookCallbacks.length;i++)
{
hookCallbacks[i].call(vm)
}
}
调用
以beforeCreate 和created 为例,在实现响应式处理数据前后分别调用。
Vue.prototype._init=function(options){const vm=this;
//将参数挂载到 vm 上
vm.$options = mergeOptions(vm.constructor.options,options);
callHook(vm,'beforeCreate');
initState(vm);
callHook(vm,'created');
if(vm.$options.el)
{
this.$mount(vm.$options.el);
}
}
测试
Vue.mixin({name2:"sss",
obj:{
a:1,
b:2
},
created:function(){
console.log('初始化了1');
}
})
Vue.mixin({
name3:"ssse",
obj:{
a:1,
b:3,
c:4
},
created:function(){
console.log('初始化了2');
}
})
var vm=new Vue({
el:"#app",
created:function(){
console.log('初始化了3');
}
})
结果
结束
简单了总结了一下Vue.mixin 方法和Vue 2的生命周期合并与调用,仅仅讲述的它的基本原理和简单实现。下一节整理总结Vue2依赖收集。
链接
- Vue2.0源码学习2:juejin.im/post/5f0112…
以上是 Vue2的源码学习3:mixin 原理的实现以及生命周期的调用 的全部内容, 来源链接: utcz.com/a/31843.html