在Vue-CLI 3腳手架項目中的src目錄下新建plugin文件夾,在該文件夾下新建MessageBox.vue,代碼如例1-1所示。
例1-1 MessageBox.vue
<template>
<div>
<h2>{{title}}</h2>
<div>
<div @click="handleOk">{{ok}}</div>
<div @click="handleCancel" v-if="cancel">{{cancel}}</div>
</div>
</div>
</template>
<script>
export default {
name: "MessageBox",
props: [""],
data() {
return {
title: '',
ok: '',
cancel: ''
};
}
}
</script>
可以看到,該組件內的數據屬性都沒有值,我們稍後會給該組件的數據屬性設置默認值。在組件內,對數據屬性cancel進行判斷,如果計算為假,則不渲染「取消」按鈕。
我們知道Vue.extend()方法可以創建一個組件的「子類」,我們可以利用這個「子類」來構造一個提示框組件對象,並設置組件的數據屬性的默認值。如下所示:
let MessageBoxImpl = Vue.extend(MessageBox);
// 調用showMessageBox函數時需要提供一個選項對象,
// 用於初始化組件內的各個選項
function showMessageBox(opts)
{
let vm = new MessageBoxImpl({
el: document.createElement("div"), //創建一個組件掛載的根元素
data() {
return {
title: opts.title ? opts.title : '',
ok: opts.ok ? opts.ok : '確定',
cancel: opts.cancel ? opts.cancel : ''
}
},
methods: {
handleOk(){
if(opts.handleOk)
// 如果外部指定了「確定」按鈕的點擊事件處理函數,
// 則調用它,使用組件的this進行綁定
opts.handleOk.call(this);
// 點擊「確定」按鈕時,從DOM中刪除提示框組件
document.body.removeChild(vm.$el);
},
handleCancel(){
if(opts.handleCancel)
// 如果外部指定了「取消」按鈕的點擊事件處理函數,
// 則調用它,使用組件的this進行綁定
opts.handleCancel.call(this);
// 點擊「取消」按鈕時,從DOM中刪除提示框組件
document.body.removeChild(vm.$el);
}
}
});
// 將組件綁定的根元素添加到HTML body元素內
document.body.appendChild(vm.$el)
}
對上述代碼進一步改良,使用閉包函數調用返回一個對外的接口。如下所示:
(function(){
// 組件數據屬性和事件響應函數的默認值
let defaults = {
title: '',
ok: '確定',
cancel: '',
handleOk: function(){},
handleCancel: function(){}
}
let MessageBoxImpl = Vue.extend(MessageBox);
return function(opts){ //配置參數
for(let attr in opts){
defaults[attr] = opts[attr];
}
let vm = new MessageBoxImpl({
el: document.createElement("div"), // 創建一個組件掛載的根元素
data() {
return {
title: defaults.title,
ok: defaults.ok,
cancel: defaults.cancel,
}
},
methods: {
handleOk(){
defaults.handleOk.call(this);
document.body.removeChild(vm.$el);
},
handleCancel(){
defaults.handleCancel.call(this);
document.body.removeChild(vm.$el);
}
}
});
document.body.appendChild(vm.$el)
}
})();
接下來將上述代碼封裝為Vue的插件,Vue的插件開發很簡單,只需要按照如下形式編寫代碼即可。
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或屬性
Vue.myGlobalMethod = function () {
// 邏輯...
}
// 2. 添加全局資源
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// 邏輯...
}
...
})
// 3. 注入組件選項
Vue.mixin({
created: function () {
// 邏輯...
}
...
})
// 4. 添加實例方法
Vue.prototype.$myMethod = function (methodOptions) {
// 邏輯...
}
}
按照上述插件開發形式編寫消息提示框插件,在plugin目錄下新建vue-msgbox.js,完整的代碼如例1-2所示。
例1-2 vue-msgbox.js
import MessageBox from './MessageBox'
const msgBox = {};
msgBox.install = function(Vue){
Vue.prototype.$msgBox = msgBox;
msgBox.show = (function(){
// 組件數據屬性和事件響應函數的默認值
let defaults = {
title: '',
ok: '確定',
cancel: '',
handleOk: function(){},
handleCancel: function(){}
}
let MessageBoxImpl = Vue.extend(MessageBox);
// 調用msgBox.show函數時需要提供一個選項對象,
// 用於初始化組件內的各個選項
return function(opts){ //配置參數
for(let attr in opts){
defaults[attr] = opts[attr];
}
let vm = new MessageBoxImpl({
el: document.createElement("div"), // 創建一個組件掛載的根元素
data() {
return {
title: defaults.title,
ok: defaults.ok,
cancel: defaults.cancel,
}
},
methods: {
handleOk(){
defaults.handleOk.call(this);
// 點擊「確定」按鈕時,從DOM中刪除提示框組件
document.body.removeChild(vm.$el);
},
handleCancel(){
defaults.handleCancel.call(this);
// 點擊「取消」按鈕時,從DOM中刪除提示框組件
document.body.removeChild(vm.$el);
}
}
});
// 將組件綁定的根元素添加到HTML body元素內
document.body.appendChild(vm.$el)
}
})();
}
export default msgBox;
接下來引入和安裝vue-msgbox插件,編輯main.js文件,添加如下的代碼:
import msgBox from './plugin/vue-msgbox'
Vue.use(msgBox)
使用插件彈出消息提示框如圖1-2所示。