欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Vue.js 源码分析(三十二) 总结

程序员文章站 2022-07-19 18:30:17
第一次写博客,坚持了一个多月时间,Vue源码分析基本分析完了,回过头也看也漏了一些地方,比如双向绑定里的观察者模式,也可以说是订阅者模式,也就是Vue里的Dep、Watcher等这些函数的作用,网上搜一下讲解也挺多的,这些知识点也是很重要的,对于阅读源码的同学这一块务必要花点时间学一下 还有一个挺重 ......

第一次写博客,坚持了一个多月时间,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一样,而且写起代码来没有冗余代码,因为你知掉它是怎么实现的了。