源码位置 vue\src\core\global-api\use
我们先从Vue.use这个API的使用开始入手:
-
请问: 如果我要注册一个Element-ui,应该怎么注册?
这不是很简单吗? 伸手就来,
import ElementUI from 'element-ui' import Vue from 'vue' Vue.use(ElementUI)
以上我们解决了如何注册element-ui, 那如果我想要编写自定义的插件呢,请看下面
问: 请实现一个
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方法呢? 实际上又是怎么运行的呢?
那么源码来了?朋友们,当你有这疑惑的时候就是该看源码的时候了,
我已经为每一个行代码,打好注释基本都不难理解
思路:
- 防止重复注册
- 截取Vue.use调用时传参
- 根据传入参数,调用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
}
}