vue.js 開發實現全域性呼叫的MessageBox元件(整合 PrimeVUE-Dialog 元件)
PrimeVUE 沒有提供全域性的 MessageBox ,在使用上總是要重覆寫 <Dialog....> ...</Dialog
>
,利用 vue.js 官方文件中的開發 Vue 外掛客制元件 來作一個全域性的 MessageBox。
- 先建立 mseeageBox 元件模板
使用 PrimeVUE-Dialog 可以省掉很多 css 匹配的問題。這個模板是呈現 UI 操作畫面,主要的程式段在 48-56 行的 comfirm()
函數裡的 new Promise((resolve,reject)
來針對按鈕: 確認 & 取消 作出相對應的 resolve & reject 。
<template> <transition name="msgbox-fade"> <Dialog :visible.sync="visible" :style="{width: '450px'}" :modal="true"> <template #header> <h4>{{header}}</h4> </template> <div class="confirmation-content"> <i :class="['pi p-mr-1',icon]" style="font-size: 2.5rem" /> <h5>{{content}}</h5> </div> <template #footer> <Button :label="cancelBtnText" class="p-button-danger p-button-sm" icon="pi pi-times" @click="handleAction('cancel')" v-if="showCancelButton" /> <Button :label="confirmBtnText" class="p-button-success p-button-sm" icon="pi pi-check" @click="handleAction('confirm')"/> </template> </Dialog> </transition> </template> <script> import i18n from '../../i18n' let typeMap = { alert: 'pi-info-circle', info: 'pi-exclamation-triangle', confirm: 'pi-question-circle', }; export default { props:{ visible:{ type: Boolean, default: false }, }, methods:{ handleAction(action){ this.visible = false; if(action==='confirm') { // 確認時, 將 promise 設為 resolve 狀態 this.resolve('confirm'); } if (action==='cancel') { // 取消時, 將 promise 設為 reject 狀態 this.reject('cancel'); } }, // 顯示對話框, 對創建 promise 物件 confirm(){ this.visible = true; this.promise = new Promise((resolve,reject) => { this.resolve = resolve; this.reject = reject; }); // 返回 promise 物件 return this.promise; } }, computed:{ cancelBtnText(){ return i18n.t("CANCEL") }, confirmBtnText(){ return i18n.t("CONFIRM") }, icon() { const { type, iconClass } = this; return iconClass || (type && typeMap[type] ? `${ typeMap[type] }` : `${ typeMap['confirm'] }`); }, header() { const {type, headerText} = this; let txt = ''; if (headerText){ return headerText; } switch (type) { case 'info': txt = i18n.t("MsgBox.INFO"); break; case 'alert': txt = i18n.t("MsgBox.ALERT"); break; case 'confirm': txt = i18n.t("MsgBox.CONFIRM"); break; default: txt = i18n.t("MsgBox.CONFIRM"); break; } return txt ; }, content() { const {contentText} = this; return contentText || i18n.t("MsgBox.CONTENT"); } }, data(){ return { resolve: '', reject: '', promise: '', //保存 promise type: '', iconClass: '', headerText: '', contentText: '', showCancelButton: true, } }, } </script> <style scoped lang="scss"> .confirmation-content { display: flex; align-items: center; justify-content: center; } </style>
- 給元件新增全域性功能
vue.js 官方文件中有開發外掛的介紹。利用 vue 的 install 方法, 將客制的 插件 msgboxVue 加入,展示的程式碼如下:
import msgboxVue from './index.vue'; // 定義插件物件 const MessageBox = {} // 利用 vue 的 install 方法, 將客制的 vue 插件加入 MessageBox.install = function (Vue) { const MessageBoxInstance = Vue.extend(msgboxVue); let currentMsg; const initInstance = () => { // 實體化 vue 物件 currentMsg = new MessageBoxInstance(); let msgBoxEl = currentMsg.$mount().$el; document.body.appendChild(msgBoxEl); }; // 在Vue的原型上加入實例方法,以便全局可以呼叫使用 Vue.prototype.$msgBox = { confirm (options) { if (!currentMsg) { initInstance(); } if (typeof options === 'string') { currentMsg.content = options; } else if (typeof options === 'object') { Object.assign(currentMsg, options); } return currentMsg.confirm() .then(val => { currentMsg = null; return Promise.resolve(val); }) .catch(err => { currentMsg = null; return Promise.reject(err); }); } }; }; export default MessageBox;
在 main.js 中註冊 MessageBox 可供全域性使用
/*main.js*/ import Vue from 'vue' import MessageBox from './components/MessageBox' Vue.use(MessageBox)
在每一個 Vue 的程式頁面方法中,就可以直接呼叫使用了
methods: { revertEvent() { const { insertRecords, removeRecords, updateRecords } = this.$refs.xTable.getRecordset() let count = updateRecords.length + removeRecords.length + insertRecords.length; if (count>0) { this.$msgBox.confirm({ contentText:'資料還原時, 編輯中的資料會遺失?!' }).then(()=>{ this.$refs.xTable.revertData() this.showResMsg('success', count + '筆資料已回覆'); }).catch(()=>{ this.showResMsg('info', count + '筆資料未回復'); }) } else { this.showResMsg('success','資料未有修改'); } } }
參考:
你必須 登入 才能發表評論。