まず、私は新しいプロジェクトVUEのinitのWebPACKのVUE-デモを作成するために、公式の足場を使用
して、私はplugins.js index.js 2つのファイルを作成します。
私はSRC /クラス/ VUE使用のディレクトリに配置された2つのファイルを持っています
これら二つの文書の次に書き込まれます
// 文件: src/classes/vue-use/plugins.js
const Plugin1 = {
install(a, b, c) {
console.log('Plugin1 第一个参数:', a);
console.log('Plugin1 第二个参数:', b);
console.log('Plugin1 第三个参数:', c);
},
};
function Plugin2(a, b, c) {
console.log('Plugin2 第一个参数:', a);
console.log('Plugin2 第二个参数:', b);
console.log('Plugin2 第三个参数:', c);
}
export { Plugin1, Plugin2 };
// 文件: src/classes/vue-use/index.js
import Vue from 'vue';
import { Plugin1, Plugin2 } from './plugins';
Vue.use(Plugin1, '参数1', '参数2');
Vue.use(Plugin2, '参数A', '参数B');
その後、我々は入り口のファイルでこのコードを引用main.js
// 文件: src/main.js
import Vue from 'vue';
import '@/classes/vue-use';
import App from './App';
import router from './router';
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App),
});
この時点では、8080のオープンな開発およびデバッグツールが情報次のコンソール出力を見ることができますNPMの実行DEV開いているポートを実行します
それは我々が3つのコンソールのインストール方法に書いたplugin1で見つけることができ、Vueのオブジェクトのうち、最初の印刷、我々は2つのパラメータを渡された第三と第二をプリントアウトしています。
plugin2でインストールしない方法は、それが第1~第3と第、Vueのオブジェクトであり、我々は2つのパラメータを渡し、それは3つのパラメータを印刷することができ、方法そのものです。
ソース解析
// Vue源码文件路径:src/core/global-api/use.js
import { toArray } from '../util/index'
export function initUse (Vue: GlobalAPI) {
Vue.use = function (plugin: Function | Object) {
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
const args = toArray(arguments, 1)
args.unshift(this)
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
installedPlugins.push(plugin)
return this
}
}
我々は最初のプラグインが登録されているか否かを判断ソースコードVUEから見ることができ、それは、重複登録を許可しません。
オブジェクト型を|し、プラグインのパラメータが受信されている機能を制限します。
両方のタイプの異なる治療法を持っています。
まず、配列=> CONST引数=のtoArray(引数、1)に編成パラメータを渡します。
toArrayソース
// Vue源码文件路径:src/core/shared/util.js
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
}
次いで、オブジェクトが開始位置に追加されたVueのアレイ(この)、この点オブジェクトのVueをargs.unshift。
私たちは、プラグインを渡した場合(最初の引数Vue.use)は、インストールの方法があります。インストール方法は、我々はオブジェクトを渡す場合、オブジェクトはインストール方法が含まれていることを意味し、我々は、このプラグインを呼び出し、インストール方法のパラメータとして渡された配列を片付けました。=> Plugin.install.apply(プラグインは、引数)
私たちはプラグインが機能で合格した場合、我々はこの関数を直接呼び出し、パラメータとして片付け配列。=> Plugin.apply(NULL、引数)
プラグインするようにアレイ上に追加されたこのプラグインを追加した後、標識既に登録されている=> installedPlugins.push(プラグイン)は
、最終的にVueのオブジェクトを返します。
概要
上記の分析を通して、私たちは私たちが後でプラグインの2つの方法ですることができ、書き込み時に、知ることができます。
一つは、最終的にはVueのは、コードオブジェクトをインストールするためにさらさ最後の書き込み操作である論理オブジェクトにパッケージを挿入することです。この方法の利点は、簡単に拡張性が比較的高い、このオブジェクトにより合理パッケージ機能をインストールするには、任意のパラメータを追加できることです。
ヴューへの暴露の関数として書かれたロジックの吸引されたすべてのもあります。
実際には、二つの方法の原理は同じですが、二以上のものを処理するための機能として直接このプラグインをインストールすることではありません。
個人的に私は最初のアプローチが合理的であると感じています。
export const Plugin = {
install(Vue) {
Vue.component...
Vue.mixins...
Vue...
// 我们也可以在install里面执行其他函数,Vue会将this指向我们的插件
console.log(this) // {install: ...,utils: ...}
this.utils(Vue) // 执行utils函数
console.log(this.COUNT) // 0
},
utils(Vue) {
Vue...
console.log(Vue) // Vue
},
COUNT: 0
}
// 我们可以在这个对象上添加参数,最终Vue只会执行install方法,而其他方法可以作为封装install方法的辅助函数
const test = 'test'
export function Plugin2(Vue) {
Vue...
console.log(test) // 'test'
// 注意如果插件编写成函数形式,那么Vue只会把this指向null,并不会指向这个函数
console.log(this) // null
}
// 这种方式我们只能在一个函数中编写插件逻辑,可封装性就不是那么强了