Vue.use为什么可以注册插件

源码位置 vue\src\core\global-api\use

我们先从Vue.use这个API的使用开始入手:

  1. 请问: 如果我要注册一个Element-ui,应该怎么注册?

    这不是很简单吗? 伸手就来,

    import ElementUI from 'element-ui'
    import Vue from 'vue'
    Vue.use(ElementUI)
    

    以上我们解决了如何注册element-ui, 那如果我想要编写自定义的插件呢,请看下面

  2. 问: 请实现一个 register.js文件,自动注册所有 filter 过滤器, 用vue.use注册

// register.js
const directives = {
    "debounce": {}, //防抖
    preview: {} //图片预览
}
export default {
    //该函数会被Vue.use执行
    install:function (Vue) {
        //遍历directives,并且安装上去
        for (const key in directives) {         
            Vue.directive(key, directives[key]);
        }
    };
}
// main.js
import Directives from 'register.js';
Vue.use(Directives)

这种比直接 import vue from 'vue' 要好,为什么这么说呢?

因为是这样的,假如: register.js,要发布到npm或者分享给同事用,此时的环境就不一定能 import vue ,意思就是可能导入不到,已经耦合在具体项目中了

但是install就不会, 想用到的地方只需要, Vue.use(register)就可以了, 无需关心这个库依赖着什么,

那么以上我们实现了两个功能,但是请问为啥我 Vue.use后,会自动执行install方法呢? 实际上又是怎么运行的呢?

那么源码来了?朋友们,当你有这疑惑的时候就是该看源码的时候了,

我已经为每一个行代码,打好注释基本都不难理解

思路:

  1. 防止重复注册
  2. 截取Vue.use调用时传参
  3. 根据传入参数,调用install方法
/* @flow */
//源码位置 vue\src\core\global-api\use
import { toArray } from '../util/index'

// 初始化Use函数
export function initUse (Vue: GlobalAPI) {
  // 传进来Vue对象,并注册一个 use函数
  Vue.use = function (plugin: Function | Object) {
    // plugin为调用 Vue.use()时,传进来的插件,可为  函数或对象

    // 取出之前安装过的插件数组,(如果没有则 初始化 = [])
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    // 查看是否注册过,防止重复注册
    if (installedPlugins.indexOf(plugin) > -1) {
      // 已经有了,直接返回 Vue
      return this
    }

    
    // additional parameters
    // 根据索引1开始到最后,从arguments拿到剩余参转成数组, [参数二,参数三]
    const args = toArray(arguments, 1) 
    //在前面添加一个 this,也就是 Vue,
    args.unshift(this)
    // 兼容可传function | object
    // 如果是对象,看看该对象是否有install方法
    if (typeof plugin.install === 'function') {
      // 有install,执行该install,并传args的参数
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') { 
      //如果是函数,直接执行即可
      plugin.apply(null, args)
    }
    // 注册过了,就添加一下,下次可以用于防止重复注册
    installedPlugins.push(plugin)
    return this
  }
}


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容