手写Vue.use、Vue.mixin、Vue.compile的时候我们讲了学习vue源码(五),讲了Vue.mixin的源码实现,还有然后我们讲到了mergeOptions这个功能的原理,并没有深入讲解。如图所示,我们这次要深入研究,所以离不开Vue中的一个重要思想:合并策略。有时候我们在面试的时候可能会遇到这样的问题:导入的mixin的数据有属性name,而我们自己注册的组件的数据也有name,那么哪个会生效呢?导入的mixin中有create,自注册的组件中有create,那么先执行哪个create呢?....其实这样的问题还有很多,要搞清楚这些问题,其实就是合并策略的问题。下面说一下大致的合并策略,方便大家在有兴趣研究源码的时候,提前理清思路。如果没有时间去了解源码,也可以先了解一下内部流程。Mixin对于解决一些奇怪的问题也非常有用。我想大家可能很少用到,但是这个东西真的很好用。相当于封装,提取公共部分。很显然,今天我不是来教大家怎么用的,只是看文档怎么用,我是在讲解生命真谛的内部工作原理。如果您不知道如何使用,请到官网查看如何使用。mixin哥难度不高,就是有点乱。今天我们来探讨两个问题1.什么时候合并2.怎么合并,什么时候合并合并分为两种1.全局mixin和合并基本全局选项的过程发生在你调用Vue之前,而且必须先发生。这样mixin就可以合并你的自定义选项Vue.mixin=function(mixin){this.options=mergeOptions(this.options,mixin);返回这个};什么是基本的全局选项?它是组件、指令和过滤器,它们从一开始就在Vue.options上设置。所以这三个是第一个全局选项。Vue.options=Object.create(null);['component','directive','filter'].forEach(function(type){Vue.options[type+'s']=Object.create(null);});这一步是在调用Vue.mixin时立即合并,然后这一步完成后全局选项例如example会变成如下,然后每个Vue实例都需要和这个全局选项合并。也许你会奇怪,我明明没有写keep-alive的这些组件,为什么我可以使用这些组件呢?其实就是这个道理。在我们新建Vue之前,源码在Vue的选项中的components数组中添加了keep-alive组件。基础组件形成后,与全局mixin合并,生成新的option。然后,我们在newVue()的时候,会传入自己的option,然后将自己的option和上面的newoption合并。2.全局选项和自定义选项的合并调用Vue时,首先要做的是mergefunctionVue(options){vm.$options=mergeOptions({globalcomponent,globaldirective,globalfilter,etc....},选项,虚拟机);...处理选项、生成模板、挂载DOM等....}options就是你传入的对象参数,然后和全局options合并。什么是全局选项?上面已经说了2.如何合并下面开始讲解各种合并策略1.函数合并叠加包括options:data,provide将两个函数合并成一个新的函数,并返回这个函数。在函数内部,这两个方法被执行。按照这个过程,codename数据中的数据重复,权重大的在前,比如下面的vartest_mixins={data(){return{name:34}}}vara=newVue({mixins:[test_mixins],data(){return{name:12}}})可以看出mixin和组件本身的data都有name数据,很明显是基于组件本身的,因为权重component本身很大2.数组叠加包含生命周期函数和watch生命周期函数的权重越大,就会合并到一个数组中,比如created[globalmixin-created,componentmixin-mixin-created,componentmixin-created,componentoptions-created]执行过程就是生命周期,权重小的先执行合并成如下数组,权重大的放在后面[globalmixin-watch,组件mixin-mixin-观看,组件mixin-观看,组件选项-观看】执行过程是监听回调3.原型叠加包括选项:components,filters,directives当两个对象合并时,不会互相覆盖,但是权重小的会放在权重大的原型上。权重大的,访问Faster,因为原型链短A.__proto__=BB.__proto__=CC.__proto__=D两个对象合并时,不会使用filter作为例子。下面是四个过滤器合并//globalfilterVue.filter("global_filter",function(params){})//mixinvarmixin_mixin={filters:{mixin_mixin_filter(){}}}//mixinfiltervartest_mixins={mixins:[mixin_mixin],filters:{mixin_filter(){}}}//Componentfiltervara=newVue({mixins:[test_mixins],filters:{self_filter(){}}})结果是这样的..4.Overlay覆盖包括选项:props,methods,computed,andinject两个对象合并。如果有重复key,权重大的会覆盖权重小的,比如componentprops:{name:""}Componentmixinprops:{name:"",age:""}然后合并两个具有相同属性的对象,具有最重要权重的对象,组件的名称将替换mixin的名称。这其实和第一种(函数合并和叠加)一样,只是第一种是函数5.直接替换这是默认的处理方式。当option不属于上述处理方式时,会这样处理,包括options:el,template,propData等两个数据只替换,不合并,权重较重。总会把权重小的替换掉,因为只允许其中一个存在,都只用权重大的option组件来设置模板,mixin也设置模板。不要害怕,必须优先考虑组件。Overlay和overlay会将两个数据合并,只有重复的才会被覆盖。而且这个不会合并,只是替换整个选项,下面结合源码说说这五种合并策略。让我们看看mergeOptions函数是什么。functionmergeOptions(parent,child,vm){//遍历mixins,parent先与mixins合并,再与child合并if(child.mixins){for(vari=0,l=child.mixins.length;i
