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打包之後所有的代碼都是封閉的,無法互相調用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章