这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战
Vue
中为开发者提供了大量的全局API,例如Vue.use
、Vue.extend
、Vue.nextTick
等,因为这些全局API的存在,方便在开发中使用和扩展一些能力
比如我们想要使用一个插件时,需要使用Vue.use(plugin)
进行全局能力的注册,可以为Vue
添加全局的方法或者属性等
initGlobalAPI
在Vue
中对于全局API是如何处理的呢?
在初始化入口提供一个initGlobalAPI
函数,调用initGlobalAPI(Vue)
进行全局API注册
初始化initGlobalAPI
函数
export function initGlobalAPI(Vue) {
}
复制代码
在函数内部会将全部的全局API进行初始化,大致如下
const ASSET_TYPES = ["component", "directive", "filter"];
export function initGlobalAPI(Vue) {
Vue.set = set;
Vue.delete = del;
Vue.nextTick = nextTick;
// 整合所有的全局相关的内容
Vue.options = Object.create(null);
ASSET_TYPES.forEach((type) => {
Vue.options[type + "s"] = Object.create(null);
});
initUse(Vue);
initMixin(Vue);
initExtend(Vue);
initAssetRegisters(Vue);
}
复制代码
Vue.use
当我们想要在Vue
项目中使用Vuex
时,就需要使用Vue.use
进行安装Vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
复制代码
在整个Vue
项目中每个组件实例都可以通过this.$stroe
来进行数据管理
Vue.use
实现:在initGlobalAPI
函数中调用initUse
函数进行全局API注册
export function initUse (Vue) {
// 在Vue上添加use函数
Vue.use = function (plugin) {
// todo...
}
}
复制代码
Vue
规定所有的插件若是一个对象,则其必须提供一个install
函数。若插件是一个函数,那么这个插件就会被当作install
函数。install
调用时会将Vue
作为第一个参数传入
/**
* 将类数组转换为数组
*/
const toArray = (list, start) => {
start = start || 0;
let i = list.length - start;
const ret = new Array(i);
// 循环类数组,将其值赋值给数组
while (i--) {
ret[i] = list[i + start];
}
// 返回生成的数组
return ret;
};
// 缓存已加载的插件
const _installedPlugins = [];
Vue.use = function (plugin) {
// 已经注册过的全部插件
const installedPlugins =
this._installedPlugins || (this._installedPlugins = []);
// 若是插件注册过,则直接返回
if (installedPlugins.indexOf(plugin) > -1) {
return this;
}
// 将第一个参数之后的数据转换为数组,一般是插件的配置项信息
const args = toArray(arguments, 1);
// 将Vue作为插件执行时第一个参数传入
args.unshift(this);
// 如果插件是一个对象且具有install函数
if (typeof plugin.install === "function") {
plugin.install.apply(plugin, args);
} else if (typeof plugin === "function") {
// 插件是一个函数,直接将插件作为install函数执行
plugin.apply(null, args);
}
installedPlugins.push(plugin);
return this;
};
复制代码