最近有些无聊,来看看vue的源码吧!
首先先找到vuejs的源码先,在平时开发的环境里(node-modules)找到vue的文件夹,然后在dist文件夹里就可以找到它了。
打开一看,一万多行! 无从下手啊,没关系。搜索“function Vue”,在4710行找到了vue的构造函数,
好短啊,怎么只有这么点(其他的应该在原型链上)。
迎面先来一个if,"development" !== 'production'貌似是打包环境之类的配置相关,这个先跳过。
this instanceof Vue的意思其实看warn也能看出来了,意思就是Vue是一个构造函数需要配合new来使用。
接下来的是_init的函数,查找一下先,在4576行找到了它。但是它是包含在一个initMixin函数中的,这个函数又是干嘛用的呢,先在这插个眼,我要先去找找这个initMixin是在什么地方被调用的。
好吧该函数在4719行被自行调用的,
传送回去看_init先,
先创建函数内部变量Vm指向this,然后创建一个内部uid=外部的uid+1,猜测这是一个当前实例的id吧
然后下面又是这个生产环境的问题,跳过。
接下来:
回到mergeOptions,下面接着是normalizeProps,在1361行找到了它,
看下来总结就是检测options里的prop是否为对象或者纯对象(dom对象等都不算),然后把props里的对象名称驼峰化。
再次回到mergeOptions,接下来normalizeInject,因该是类似上面的方法,跳过。再下来是normalizeDirectives 。。也跳过
然后:
var extendsFrom = child.extends;
if (extendsFrom) {
parent = mergeOptions(parent, extendsFrom, vm);
}
options里有extends么?查了一下是和mixins类似的属性,mixins又是什么。。。 (minxins混入对象请自行查询)
接下来就是对mixins属性对象的处理了,总的来说这两个属性就是会自带vue的实例对象或者函数,也需要进行净化内部数据(mergeOptions())。
然后:
先新建一个options,然后分别循环vue构造函数和准备新建实例的options,在这里面有一个mergeField的函数, 先看第一行:
var strat = strats[key] || defaultStrat;
这里要注意的是,strats其实是只是用来创建一个空对象的小勾子:
现在就很明显了,mergeOptions这个函数是用来净化实例options各个key的,然后把构造函数里的各个key和新实例中的各个key进行合并,如果碰到同名属性,以实例的为准(这个很好理解,css的样式优先级也是这样,范围越小优先度越高)