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
  };

writer by:大沙漠 QQ:22969969

也就是说执行插件的install函数时,函数内的上下文为Vue实例,然后就可以在Vue内部的生命周期内执行各种操作了,这就是插件的逻辑了。

mixin就是混入的意思,也就是把对象里的信息保存到Vue实例的options上,一般是混入一些生命周期函数,源码就一行,保存到Vue实例的options上,我就不贴了。

从整体来看,Vue只是一个匿名函数,该函数会在window.Vue这个属性上挂载一个函数,然后在该函数本身或函数原型上定义一些属性、操作如此而已,只是Vue定义的属性和操作比多,看起来复杂,例如Vue有一万多行代码,不只是Vue,大多话前端框架基本都是这个设计模式吧(通过执行一个匿名函数来给window挂载一个属性作为调用的接口)。

理解源码有一个好处就是用起来真的很爽,比如我现在工作用到Vue时就和算算术题1+1=2一样,而且写起代码来没有冗余代码,因为你知掉它是怎么实现的了。

原文地址:https://www.cnblogs.com/greatdesert/p/11300263.html