您好,登錄后才能下訂單哦!
vue.use(plugin, arguments) 語法
參數(shù):plugin(Function | Object)
用法:
如果vue安裝的組件類型必須為Function或者是Object
如果是個(gè)對(duì)象,必須提供install方法
如果是一個(gè)函數(shù),會(huì)被直接當(dāng)作install函數(shù)執(zhí)行
install函數(shù)接受參數(shù),默認(rèn)第一個(gè)參數(shù)為Vue,其后參數(shù)為注冊(cè)組件時(shí)傳入的arguments
先舉個(gè)?
我們先來看一個(gè)簡單的事例
首先我使用官方腳手架新建一個(gè)項(xiàng)目vue init webpack vue-demo
然后我創(chuàng)建兩個(gè)文件index.js plugins.js.
我將這兩個(gè)文件放置在src/classes/vue-use目錄下
接下來對(duì)這兩個(gè)文件進(jìn)行編寫
// 文件: src/classes/vue-use/plugins.js const Plugin1 = { install(a, b, c) { console.log('Plugin1 第一個(gè)參數(shù):', a); console.log('Plugin1 第二個(gè)參數(shù):', b); console.log('Plugin1 第三個(gè)參數(shù):', c); }, }; function Plugin2(a, b, c) { console.log('Plugin2 第一個(gè)參數(shù):', a); console.log('Plugin2 第二個(gè)參數(shù):', b); console.log('Plugin2 第三個(gè)參數(shù):', c); } export { Plugin1, Plugin2 };
// 文件: src/classes/vue-use/index.js import Vue from 'vue'; import { Plugin1, Plugin2 } from './plugins'; Vue.use(Plugin1, '參數(shù)1', '參數(shù)2'); Vue.use(Plugin2, '參數(shù)A', '參數(shù)B');
然后我們?cè)谌肟谖募ain.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), });
此時(shí)我們執(zhí)行npm run dev打開8080端口開啟開發(fā)調(diào)試工具可以看到控制臺(tái)輸出以下信息
...]
從中可以發(fā)現(xiàn)我們?cè)趐lugin1中的install方法編寫的三個(gè)console都打印出來,第一個(gè)打印出來的是Vue對(duì)象,第二個(gè)跟第三個(gè)是我們傳入的兩個(gè)參數(shù)。
而plugin2沒有install方法,它本身就是一個(gè)方法,也能打印三個(gè)參數(shù),第一個(gè)是Vue對(duì)象,第二個(gè)跟第三個(gè)也是我們傳入的兩個(gè)參數(shù)。
那么現(xiàn)在我們是不是大概對(duì)Vue.use有一個(gè)模糊的猜想~
分析源碼
好我們還是不要猜想,直接上源碼
// 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 } }
從源碼中我們可以發(fā)現(xiàn)vue首先判斷這個(gè)插件是否被注冊(cè)過,不允許重復(fù)注冊(cè)。
并且接收的plugin參數(shù)的限制是Function | Object兩種類型。
對(duì)于這兩種類型有不同的處理。
首先將我們傳入的參數(shù)整理成數(shù)組 => const args = toArray(arguments, 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對(duì)象添加到這個(gè)數(shù)組的起始位置args.unshift(this),這里的this 指向Vue對(duì)象
如果我們傳入的plugin(Vue.use的第一個(gè)參數(shù))的install是一個(gè)方法。也就是說如果我們傳入一個(gè)對(duì)象,對(duì)象中包含install方法,那么我們就調(diào)用這個(gè)plugin的install方法并將整理好的數(shù)組當(dāng)成參數(shù)傳入install方法中。 => plugin.install.apply(plugin, args)
如果我們傳入的plugin就是一個(gè)函數(shù),那么我們就直接調(diào)用這個(gè)函數(shù)并將整理好的數(shù)組當(dāng)成參數(shù)傳入。 => plugin.apply(null, args)
之后給這個(gè)插件添加至已經(jīng)添加過的插件數(shù)組中,標(biāo)示已經(jīng)注冊(cè)過 => installedPlugins.push(plugin)
最后返回Vue對(duì)象。
小結(jié)
通過以上分析我們可以知道,在我們以后編寫插件的時(shí)候可以有兩種方式。
一種是將這個(gè)插件的邏輯封裝成一個(gè)對(duì)象最后將最后在install編寫業(yè)務(wù)代碼暴露給Vue對(duì)象。這樣做的好處是可以添加任意參數(shù)在這個(gè)對(duì)象上方便將install函數(shù)封裝得更加精簡,可拓展性也比較高。
還有一種則是將所有邏輯都編寫成一個(gè)函數(shù)暴露給Vue。
其實(shí)兩種方法原理都一樣,無非第二種就是將這個(gè)插件直接當(dāng)成install函數(shù)來處理。
個(gè)人覺得第一種方式比較合理。
舉個(gè)?
export const Plugin = { install(Vue) { Vue.component... Vue.mixins... Vue... // 我們也可以在install里面執(zhí)行其他函數(shù),Vue會(huì)將this指向我們的插件 console.log(this) // {install: ...,utils: ...} this.utils(Vue) // 執(zhí)行utils函數(shù) console.log(this.COUNT) // 0 }, utils(Vue) { Vue... console.log(Vue) // Vue }, COUNT: 0 } // 我們可以在這個(gè)對(duì)象上添加參數(shù),最終Vue只會(huì)執(zhí)行install方法,而其他方法可以作為封裝install方法的輔助函數(shù) const test = 'test' export function Plugin2(Vue) { Vue... console.log(test) // 'test' // 注意如果插件編寫成函數(shù)形式,那么Vue只會(huì)把this指向null,并不會(huì)指向這個(gè)函數(shù) console.log(this) // null } // 這種方式我們只能在一個(gè)函數(shù)中編寫插件邏輯,可封裝性就不是那么強(qiáng)了
小弟不才,對(duì)vue源碼的理解暫且到這。歡迎大佬們多指教~
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。