Vue.use源码分析

我想有过 vue 开发经验的,对于 vue.use 并不陌生。当使用 vue-resource 或 vue-router 等全局组件时,必须通过 Vue.use 方法引入,才起作用。那么 vue.use 在组件引入之前到底做了那些事情呢?让我们一窥究竟。

先上 vue.use 源码

Vue.use = function (plugin) {
    /* istanbul ignore if */
    if (plugin.installed) {
      return
    }
    // additional parameters
    var args = toArray(arguments, 1);
    args.unshift(this);
    if (typeof plugin.install === 'function') {plugin.install.apply(plugin, args);
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args);}
    plugin.installed = true;
    return this
  };

假设我们通过 Vue.use 引入一个插件 plugin(该插件可以暂时理解为一个变量或参数), 即 Vue.use(plugin);

首先判断传入的参数 plugin 的属性 installed 是否存在,如果存在且逻辑值为真,那么直接返回,后边的代码就不会在执行,这个判断的作用是什么呢?后边会讲到。

我们先假设 plugin 的属性 installed 不存在或为假,那么继续往下执行

var args = toArray(arguments, 1);
// 执行了一个 toArray 方法,toArray 接收了两个参数,arguments 为 Vue.use 方法传入的参数集合,例如 Vue.use(a,b,c), 那么 arguments 类似于 [a,b,c](说明:arguments 只是类数组,并不是真正的数组)
此处因为我们只引入一个参数 plugin, 所以 arguments 类似于 [plugin]。

toArray 的作用是什么呢?看源码。

function toArray (list, start) {
  start = start || 0;
  var i = list.length - start;
  var ret = new Array(i);
  while (i--) {ret[i] = list[i + start];
  }
  return ret
}

当执行 toArray(arguments,1),会生成一个新数组 ret,长度 = arguments.length-1,然后进行 while 循环,依次倒序把 arguments 的元素赋值给 ret, 因为 ret 比 arguments 长度少 1,所以最终等同于arguments 把除了第一个元素外的其余元素赋值给 ret。toArray 主要作用就是把类数组转化为真正的数组,这样才能调用数组的方法。因为此处我只引入一个 plugin 参数,即 arguments=[plugin],所以 toArray 返回为空数组 []。

接着往下执行,args.unshift(this),等同于 [].unshift(Vue), 即 args = [Vue];

然后执行

if (typeof plugin.install === 'function') {plugin.install.apply(plugin, args);
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args);}

此处判断 plugin 的 install 是否为函数,如果为函数,立即执行 pluign.install 方法,install 方法传入的参数为 args 内数组元素,即 install 接受的第一个参数为 Vue.

如果 plugin 的 install 不是函数,那么判断 plugin 本身是否为函数,如果为函数,那么执行 plugin 函数,且参数为 args 内数组元素。

最后设置 plugin.installed 为 true。设置 plugin.installed 为 true 的作用是避免同一个插件多次执行安装,比如 Vue.use(plugin) 执行一次之后,installed 为 true, 再次执行的话走到第一步判断就返回了。

综上所述,Vue.use 的作用其实就是执行一个 plugin 函数或者执行 pluign 的 install 方法进行插件注册,并且向 plugin 或其 install 方法传入 Vue 对象作为第一个参数,use 的其他参数作为 plugin 或 install 的其他参数。

举个简单的例子

import Vue from 'vue'
function test(a){
console.log(a);//Vue
}
function test1(a,b){
  console.log(a,b);//Vue hello
}
let oTest = {
install:function(a,b){
console.log(a,b);//Vue hello1
}
}

Vue.use(test);
Vue.use(test1,'hello');
Vue.use(oTest,'hello1')
console.log(oTest);
//{
  install:function(){...},
  installed:true
}
 

 

个人博客传送门》》》》》