相信Vue.use,使用vue的同學經常會用到,那麼使用Vue.use(插件)時,發生了什麼,讓我們看一下。

Vue.use(VueRouter)

Vue.use(ElementUI)等等

自定義一個全局Loading組件,並使用:

總結目錄
|-components
  |-loading
    |-index.js 導出組件並且install
    |-loading.vue 定義Loading組件這裡面基本的style ,script中之前講的methods,data方法都可以使用
index.js中的代碼
import LoadingComponent from ./loading.vue
  const Loading={
    install:function(Vue){ //核心部分,在我們使用Vue.use()時,自動調用的是install,而install導出的必須是的組件
    Vue.component(loading,LoadingComponent);
  }
};
export default Loading;
main.js中要使用
  import loading from ./components/loading
  Vue.use(loading); //調用的是install裡面的組件

一個簡易demo

common.js
export default {
install: function(Vue){
Vue.prototype.$img = {
baseUrl = http://localhost:8888
}
}
}

//main.js
import common from ./js/common.js
Vue.use(common)

分析源碼

// 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首先判斷這個插件是否被註冊過,不允許重複註冊。

並且接收的plugin參數的限制是Function | Object兩種類型。

對於這兩種類型有不同的處理。

首先將我們傳入的參數整理成數組 =>const args = toArray(arguments, 1)

// 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對象添加到這個數組的起始位置args.unshift(this),這裡的this 指向Vue對象

如果我們傳入的plugin(Vue.use的第一個參數)的install是一個方法。也就是說如果我們傳入一個對象,對象中包含install方法,那麼我們就調用這個plugininstall方法並將整理好的數組當成參數傳入install方法中。 =>plugin.install.apply(plugin, args)

如果我們傳入的plugin就是一個函數,那麼我們就直接調用這個函數並將整理好的數組當成參數傳入。 =>plugin.apply(null, args)

之後給這個插件添加至已經添加過的插件數組中,標示已經註冊過 =>installedPlugins.push(plugin)

最後返回Vue對象。

小結

通過以上分析我們可以知道,在我們以後編寫插件的時候可以有兩種方式。

一種是將這個插件的邏輯封裝成一個對象最後將最後在install編寫業務代碼暴露給Vue對象。這樣做的好處是可以添加任意參數在這個對象上方便將install函數封裝得更加精簡,可拓展性也比較高。

還有一種則是將所有邏輯都編寫成一個函數暴露給Vue。

其實兩種方法原理都一樣,無非第二種就是將這個插件直接當成install函數來處理。

個人覺得第一種方式比較合理。

Vue組件開發

1,文件loading.vue 中定義一個組件

<template>
<div class="loading-box">
Loading...
</div>
</template>

2,在index.js 中 引入 loading.vue ,並導出

// 引入組件
import LoadingComponent from ./loading.vue
// 定義 Loading 對象
const Loading={
// install 是默認的方法。當外界在 use 這個組件的時候,就會調用本身的 install 方法,同時傳一個 Vue 這個類的參數。
install:function(Vue){
Vue.component(Loading,LoadingComponent)
}
}
// 導出
export default Loading

3,在 main.js 中引入 loading 文件下的 index.js

// 其中『./components/loading/index『 的 /index 可以不寫,webpack會自動找到並載入 index 。如果是其他的名字就需要寫上。
import Loading from ./components/loading/index
// 這時需要 use(Loading),
Vue.use(Loading)

4,在其他vue文件中引用Vue組件,寫入定義好的組件標籤<Loading></Loading>

<template>
<div id="app">
<h1>vue-loading</h1>
<Loading></Loading>
</div>
</template>

推薦閱讀:

相关文章