vue.use 实现原理剖析 All In One
vue.use 实现原理剖析 All In One
插件通常用来为 Vue 添加全局功能。
插件的功能范围没有严格的限制, 一般有下面几种:
-
添加全局方法或者 property。如:vue-custom-element
-
添加全局资源:指令/过滤器/过渡等。如 vue-touch
-
通过全局混入来添加一些组件选项。如 vue-router
-
添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
-
一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router
源码解读
/**
* Convert an Array-like object to a real Array.
*/
export function toArray (list: any, start?: number): Array<any> {
start = start || 0
let i = list.length - start
const ret: Array<any> = new Array(i)
while (i--) {
ret[i] = list[i + start]
}
return ret
}
util/index
=> shared/util.js
https://github.com/vuejs/vue/blob/master/src/shared/util.js
/* @flow */
import { toArray } from '../util/index'
export function initUse (Vue: GlobalAPI) {
// 闭包
Vue.use = function (plugin: Function | Object) {
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
// plugin 已存在, 直接返回,防止重复添加
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
// 把 arguments 转换成 apply 支持的参数数组形式
const args = toArray(arguments, 1)
// 从数组前面插入 this
args.unshift(this)
if (typeof plugin.install === 'function') {
// plugin 是个对象,而且有 install 方法
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
// plugin 本身是个方法
plugin.apply(null, args)
}
// 收集 plugin
installedPlugins.push(plugin)
return this
}
}
https://github.com/vuejs/vue/blob/dev/src/core/global-api/use.js
https://github.com/vuejs/vue/blob/master/src/core/global-api/use.js
Vue 2.x
全局方法 Vue.use() 使用插件, 必须放在调用 new Vue() 前。
Vue.use(MyPlugin);
// 调用插件的 install 方法 `MyPlugin.install(Vue)`;
// Vue.use(MyPlugin, { someOption: true });
new Vue({
// ...
});
// 用 Browserify 或 webpack 提供的 CommonJS 模块环境时
var Vue = require('vue');
var VueRouter = require('vue-router');
// 手动调用插件
Vue.use(VueRouter);
// 检查到全局变量 Vue 后才调用插件 ✅
if(globalThis.Vue) {
Vue.use(VueRouter);
}
if(globalThis.Vue) {
console.log('globalThis.Vue =', typeof globalThis.Vue);
}
// globalThis.Vue = function
自定义插件
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或 property
Vue.myGlobalMethod = function () {
// ...
};
// 2. 添加全局资源 (指令/过滤器/过渡)
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// ...
},
//...
});
Vue.directive('my-filter', function (value) {
if (!value || typoef value !== 'string') {
return '';
}
return `${value[0].toUpperCase()}${value.slice(1)}`;
// value =
// return value.charAt(0).toUpperCase() + value.slice(1);
});
// 3. 全局混入/全局注入一些组件选项
Vue.mixin({
created: function () {
// ...
console.log('created', mixin);
},
//...
data () {
isLoading: false,
isDebugging: false,
},
methods: {
log(value) {
// 打印组建名称
const componetName = `✅👍🚀 ${this.name}` || '❌👎💩 Anonymous Component';
console.log(`${componetName}'s value =`, value);
},
},
});
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
// ...
};
Vue.prototype.monitor = function (options = {}) {
// 监控 SDK
console.log('上报数据', options);
};
}
https://cn.vuejs.org/v2/api/#Vue-use
https://cn.vuejs.org/v2/guide/plugins.html
Vue 3.x
https://v3.cn.vuejs.org/guide/plugins.html
demo
refs
©xgqfrms 2012-2020
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/15983128.html
未经授权禁止转载,违者必究!