Vue.js 源码分析(三十二) 总结
第一次写博客,坚持了一个多月时间,vue源码分析基本分析完了,回过头也看也漏了一些地方,比如双向绑定里的观察者模式,也可以说是订阅者模式,也就是vue里的dep、watcher等这些函数的作用,网上搜一下讲解也挺多的,这些知识点也是很重要的,对于阅读源码的同学这一块务必要花点时间学一下
还有一个挺重要是vue的一个use和mixin方法,这两个方法用于vue插件的注册,比如vuex、vuex-router等等都是通过vue.use()来注册的,注册完后会执行对应插件的install方法进行安装,例如对于vuex来说:
if (version >= 2) { vue.mixin({ beforecreate: vuexinit }); //对于vuex来说,通过mixin混入,在vue的beforecreate生命周期函数内插入一个vuexinit方法 } else { // override init and inject vuex init procedure // for 1.x backwards compatibility. var _init = vue.prototype._init; vue.prototype._init = function (options) { if ( options === void 0 ) options = {}; options.init = options.init ? [vuexinit].concat(options.init) : vuexinit; _init.call(this, options); }; }
对于vue-router来说,如下:
vue.mixin({ //对于vue-router来说,通过mixin混入,在vue的beforecreate和destroyed生命周期函数内分别插入两个函数体 beforecreate: function beforecreate () { if (isdef(this.$options.router)) { this._routerroot = this; this._router = this.$options.router; this._router.init(this); vue.util.definereactive(this, '_route', this._router.history.current); } else { this._routerroot = (this.$parent && this.$parent._routerroot) || this; } registerinstance(this, this); }, destroyed: function destroyed () { registerinstance(this); } });
当我们执行vue.use(vuex)或者vue.use(router)安装vuex或vue-router插件时,就会执行vue内部的use函数接口,如下:
vue.use = function (plugin) { //第4728行 注册插件用 var installedplugins = (this._installedplugins || (this._installedplugins = [])); //获取当前vue已经注册的插件列表 if (installedplugins.indexof(plugin) > -1) { //如果plugin插件已经注册过了 return this //直接返回,不做处理 } // additional parameters var args = toarray(arguments, 1); //去掉第一个参数 args.unshift(this); //然后将大vue放进去 if (typeof plugin.install === 'function') { //如果有该插件有install方法 plugin.install.apply(plugin, args); //执行该install方法,参数为args(第一个参数为大vue的实例) } else if (typeof plugin === 'function') { plugin.apply(null, args); } installedplugins.push(plugin); //将插件plugin保存到installedplugins里面,避免多次执行use时重复安装 return this };
也就是说执行插件的install函数时,函数内的上下文为vue实例,然后就可以在vue内部的生命周期内执行各种操作了,这就是插件的逻辑了。
mixin就是混入的意思,也就是把对象里的信息保存到vue实例的options上,一般是混入一些生命周期函数,源码就一行,保存到vue实例的options上,我就不贴了。
从整体来看,vue只是一个匿名函数,该函数会在window.vue这个属性上挂载一个函数,然后在该函数本身或函数原型上定义一些属性、操作如此而已,只是vue定义的属性和操作比多,看起来复杂,例如vue有一万多行代码,不只是vue,大多话前端框架基本都是这个设计模式吧(通过执行一个匿名函数来给window挂载一个属性作为调用的接口)。
理解源码有一个好处就是用起来真的很爽,比如我现在工作用到vue时就和算算术题1+1=2一样,而且写起代码来没有冗余代码,因为你知掉它是怎么实现的了。