一、為什麼要自己動手寫外掛呢,原因有二:
其一:是因為最近產品了提了一個在web端接收,訊息通知的需求,產品要求在若干個頁面內如果有訊息,就要彈出訊息彈窗展示給使用者,略加思索之後,第一反應就是寫個訊息的元件,在需要的頁面引入,不過寫好之後,發現這樣寫好麻煩,是不是可以寫個外掛在全域性一次性引入呢?
其二:純粹的想學習一下vue的外掛是如何開發的
二、既然有想法了,那就開始寫唄,先去檢視了vue的官方文件,官方文件介紹如下:
外掛通常用於為 Vue 新增全域性級別的功能。然而對於外掛,並沒有嚴格限定其使用範圍 – 下面是常見的幾種外掛型別:
新增一些全域性方法或屬性。
新增一個或多個全域性資源(asset):指令(directives)/過濾器(filters)/過渡(transitions) 等。
通過全域性 mixin,新增一些元件選項。
新增一些 Vue 例項方法,通過把這些方法新增到 Vue.prototype 上實現。
一個可以提供 API 的庫(library),與此同時也是以上功能的組合。
Vue.js 外掛應該暴露一個 install 方法。此方法在呼叫時,將 Vue 建構函式作為第一個引數傳入,以及將一個可選的選項作為第二個引數傳入:
MyPlugin.install = function (Vue, options) {
// 1. 新增全域性方法或屬性
Vue.myGlobalMethod = function () {
// 一些邏輯……
}
// 2. 新增一個全域性資源(asset)
Vue.directive(`my-directive`, {
bind (el, binding, vnode, oldVnode) {
// 一些邏輯……
}
...
})
// 3. 注入一些元件選項
Vue.mixin({
created: function () {
// 一些邏輯……
}
...
})
// 4. 新增一個例項方法
Vue.prototype.$myMethod = function (methodOptions) {
// 一些邏輯……
}
}
通過呼叫全域性方法 Vue.use() 使用外掛:
// 呼叫 `MyPlugin.install(Vue)`
Vue.use(MyPlugin)
可以根據情況,傳入一些可選的選項:
Vue.use(MyPlugin, { someOption: true })
Vue.use 會自動阻止多次使用同一個外掛,所以對於同一個外掛的多次呼叫,將只安裝一次。
三、看完文件我們就開始動手寫唄(以loading外掛為例)
var Loading = {}
var showLoad = false
var loadNode = {}
Loading.install = function (Vue, options) {
Vue.prototype.$loading = function (type) {
if (type === `close`) {
loadNode.show = showLoad = false
document.querySelector(`.loadEffect`).remove()
} else {
if (showLoad) {
return
}
let LoadingTpl = Vue.extend({
data: function () {
return {
show: showLoad
}
},
template: `<div class="loadEffect"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><p class="loadings">loading....</p></div>
`
})
let tpl = new LoadingTpl().$mount().$el
document.body.appendChild(tpl)
loadNode.show = showLoad = true;
[`open`, `close`].forEach(function (type) {
Vue.prototype.$loading[type] = function () {
return Vue.prototype.$loading(type)
}
})
}
}
}
export default Loading
然後在我們的元件中使用this.$loading來使用,發現沒有任何問題。。。。。
但是。。。嘿嘿,總有但是,,沒錯下面的場景就是萬惡的但是。。。。
因為我們發現我們編寫的這個外掛只能在vue元件中使用,如果我想在axios的攔截器中使用這個外掛呢?顯然用不了,這是為什麼呢?是因為我們在axios中沒有訪問到vue的例項,因為我們的外掛是過載在vue的例項上的
現在怎麼辦,百度看了很多別人寫的部落格,不出意外,對就是那個不出意外,沒有找到合適的解決方案!!!!!!!!!!!!!!!!!
怎麼辦呢?放棄?不可能,這輩子是不可能放棄的!!!下輩子也不可能的!!!那怎麼辦?嘿嘿,世面上還是有很多牛叉的UI庫的比如element-ui,然後自己去試了一下,發現element-ui不僅在vue元件中可以使用,也可以在axios的攔截器這中呼叫
既然發現了,那就去檢視他們的原始碼,看看大佬們是如何實現的,不看不知道,一看嚇一跳,老大的程式碼果然性感,下面貼出我自己刪減後實現這個功能的核心程式碼
const Message = function (options) {
options = options || {}
options = {
message: options.message,
name: options.name,
state: options.state
}
instance = new MessageConstructor({
data: options
})
instance.vm = instance.$mount()
document.body.appendChild(instance.vm.$el)
}
Vue.prototype.$message = Message
下面貼出原始碼地址
https://github.com/songdongdo…
如果對您有幫助請不要吝嗇您的start
我的原文部落格地址:http://www.cnblogs.com/songdo…