Vue.use原始碼解析
什麼是Vue外掛
關於什麼是Vue外掛大家可以去看官網的解釋 ,總得來說就是提供一個全域性註冊/呼叫的能力。
怎麼用
我們以Weex為例。
首先有一個toast.js
const Toast = {} Toast.install = (Vue, options) => { Vue.prototype.$toast = (msg, duration = 0.8) => { const modal = weex.requireModule('modal') modal.toast({ message: msg, duration: 0.8 }) } } Vue.use(Toast)
前端全棧學習交流圈:866109386,面向1-3經驗年前端開發人員,幫助突破技術瓶頸,提升思維能力,群內有大量PDF可供自取,更有乾貨實戰專案視訊進群免費領取。
很簡單,就是定義了一個Toast對面,然後給Toast物件建立一個install方法,方法裡給Vue的prototype建立了一個$toast方法,該方法就是呼叫modal去彈一個toast,最後使用Vue.use方法去註冊這個Toast外掛。
然後我們還有一個index.vue:
<template> <div> <div class="box" @click="onclick" @longpress="onlongpress" @appear="onappear" @disappear="ondisappear"></div> </div> </template> <script> const modal = weex.requireModule('modal') export default { methods: { onclick (event) { this.$toast("aaa", 0.8) }, onlongpress (event) { console.log('onlongpress:', event) modal.toast({ message: 'onlongpress', duration: 0.8 }) }, onappear (event) { console.log('onappear:', event) modal.toast({ message: 'onappear', duration: 0.8 }) }, ondisappear (event) { console.log('ondisappear:', event) modal.toast({ message: 'ondisappear', duration: 0.8 }) } } } </script> <style scoped> .box { border-width: 2px; border-style: solid; border-color: #BBB; width: 250px; height: 250px; margin-top: 250px; margin-left: 250px; background-color: #EEE; } </style>
前端全棧學習交流圈:866109386,面向1-3經驗年前端開發人員,幫助突破技術瓶頸,提升思維能力,群內有大量PDF可供自取,更有乾貨實戰專案視訊進群免費領取。
在其中呼叫了this.$toast去使用外掛的方法。
由此我們可以知道,Vue的外掛機制就是通過Vue.use方法去註冊的。
原始碼分析
Vue.use = function (plugin) { if (plugin.installed) { return } var 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); } plugin.installed = true; return this }; function toArray (list, start) { start = start || 0; var i = list.length - start; var ret = new Array(i); while (i--) { ret[i] = list[i + start]; } return ret }
use方法非常簡單:
0x01:判斷該外掛是否已經註冊,如果已經註冊就直接return,防止重複註冊。
0x02:然後通過toArray方法將Arguments這個類陣列轉換成真正的資料,並且去掉第一個元素。
0x03:將this,也就是Vue例項新增到toArray生成的args陣列中。
0x04:判斷use的入參plugin是install是否是一個方法,如果是則直接呼叫該方法。
0x05:如果第四步是false,則判斷plugun本身是不是一個方法,如果是方法,則用它本身代替install去執行。
0x06:將plugin的installed標記位設定為true。
就這麼簡單的6步,use方法就分析完了,其實就是為了去執行外掛的install方法,而結合上面的例子我們知道,install中就把$toast賦值給了Vue的prototype,在其他地方就可以使用的。
結合實際場景
學習了Vue的外掛機制,那麼這個機制我們能用來做什麼呢?我們結合Weex來看。
首先我們知道,Weex是把bundle下發到客戶端並渲染,所以一個頁面的載入時間取決於兩部分:bundle下載時間,bundle渲染時間。在不考慮本地快取的情況下,bundle的大小直接決定了它的下載時間,以及使用者所消耗的流量,所以我們需要有一種方式去儘可能的減小這個bundle的體積。這裡Vue的外掛機制就可以排上用場了。
首先我們把一部分共用,不太會改動的基礎的程式碼放在客戶端,這樣bundle裡的內容就應該是純業務相關的程式碼,在把bundle下載下來之後手動將客戶端的基礎js拼接到bundle上,這樣就能有效地減小bundle的體積,而想要使用這種方式,就必須把基礎js通過Vue的外掛機制註冊,業務js中全域性呼叫,不然是無法拼接的(除非你的基礎js不通過webpack打包),畢竟webpack打包之後所有的程式碼都是封閉的,無法互相呼叫。