Vue.use原理及源码解读

·  阅读 632

vue.use(plugin, arguments) 入参

use<T>(plugin: PluginObject<T> | PluginFunction<T>, options?: T): void;
use(plugin: PluginObject<any> | PluginFunction<any>, ...options: any[]): void;
复制代码

由上面代码可以看到第一个插件参数 plugin 接受一个 obj 或者一个 fn , 第二个参数可选的一个数组(泛型是什么自己百度下楼~)那么接下来继续

export type PluginFunction<T> = (Vue: typeof _Vue, options?: T) => void;
export interface PluginObject<T> {
  install: PluginFunction<T>;
  [key: string]: any;
}
复制代码

PluginObject如果是一个对象,对象必须有install方法才行,PluginFunction如果作为一个函数没有返回值哦。

function initUse (Vue)

入参已经明确了,我们来看下,use发生了什么,我们在 initGlobalAPI 发现了 initUse 方法。

function initUse (Vue) {
  Vue.use = function (plugin) {
    // 定义查看已经被注册的组件,installedPlugins
    var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
    // 如果传入的组件已经被注册 直接返回实例
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }
    
    // additional parameters(获取附加参数)
    var args = toArray(arguments, 1);
    // 向头部添加this
    args.unshift(this);
    // 判断入参是否有install方法
    if (typeof plugin.install === 'function') {
      // 有执行,动态改this为plugin
      plugin.install.apply(plugin, args);
    } else if (typeof plugin === 'function') {
      // 插件本身就是fn,动态改this为null
      plugin.apply(null, args);
    }
    // 已注册插件列表添加插件
    installedPlugins.push(plugin);
    return this
  };
}
复制代码

扩展

我们看到了 toArray 方法了那我们来看一下吧

/**
 * Convert an Array-like object to a real Array.
 */
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
}
复制代码

通过注释 我们能看到就是把类数组变成真数组的一个方法,这里大家可以想象用es6怎么转换~现在的语法糖真是越来越简单了。

总结

好了今天的use分析完了,我们看到了use的流程就是:

  • 先验证传进来的插件是否注册,存在即返回保证只注册一次。

  • 没注册的插件来判断插件类型。如果是对象必须有install方法,如果是函数直接插入。(记得改变this指向哦~)

  • 最后添加到已注册的插件列表里。


如果这篇文章有用,欢迎评论, 点赞, 加关注

我是leo:祝大家早日升职加薪。

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改