淺談Vue.use與Vue組件開發
相信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
方法,那麼我們就調用這個plugin
的install
方法並將整理好的數組當成參數傳入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>
推薦閱讀: