【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

.Ping發表於2020-03-28

前言

最近公司專案比較忙,導致之前的排序沒時間更新,等後面有空再繼續。

如題所述,各位大佬平時專案中肯定針對MessageBox進行了二次封裝,如果大佬們有什麼好的封裝方法和建議希望多多留言,給萌新一個學習的機會。

【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

序曲

先說一下故事的起因:

今天想對elementUI的MessageBox進行一下二次封裝,畢竟每次都要寫一堆重複程式碼還是挺蛋疼的事情。

【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

開搞!!

正文

此處我們只對最基本的內容進行封裝包含:標題(title)、訊息內容(message)、提示型別(type)還有回撥函式(callback),catch不做任何操作

單獨引用

後面所有案例均單獨引用MessageBox,

import { MessageBox } from "element-ui";
複製程式碼

原始程式碼

    MessageBox.confirm('此操作將永久刪除該檔案, 是否繼續?', '提示', {
        confirmButtonText: '確定',
        cancelButtonText: '取消',
        type: 'warning'
    }).then(() => {
        console.log('這裡是回撥哦')
    })
複製程式碼

普通版

眾所周知:confirm用的是 Promise 來處理後續響應。

所以MessageBox.confirm就是一個Promise物件,那麼最簡單的就是直接返回confirm方法:

export function MessageConfirm2({ 
    content: content = "確認操作?", 
    tip: tip = "提示", 
    type: type = "warning" 
} = { content: "確認操作?", tip: "提示", type: "warning" }) {
    return MessageBox.confirm(content, tip, {
        confirmButtonText: '確定',
        cancelButtonText: '取消',
        type: type,
    })
}
複製程式碼

使用的話:

// 引入
import { MessageConfirm } from "@/utils/confirm"
MessageConfirm().then(res => {
	console.log('是的沒錯,回撥寫在這裡就行了')
})
複製程式碼

毫無疑問的結果:

【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

個人魔改版

在封裝程式碼的時候突然想到之前寫過一個Promise的手寫版(我也不知道為什麼就突然想到了,雖然那篇寫的很爛),那我能不能把MessageBox封裝成Promise那樣,哪樣?

const promise = new Promise((resolve,reject)=>{
    // ...
    resolve(true);
    // ...
    reject(false);
})
複製程式碼

想造作就造作起來吧。

export class MessageTips {
    constructor(fn) {
        this.status = 'pending';
        this.confirmFn = [];
        this.alertFn = [];
        this.promotFn = [];
        const confirm = ({ content: content = "確認操作?", tip: tip = "提示", type: type = "warning" } = { content: "確認操作?", tip: "提示", type: "warning" }) => {
            if(this.status == 'pending'){
                this.content = content;
                this.tip = tip;
                this.type = type;
                this.status = 'confirm';
                this.confirmFn.forEach(item => {
                    item();
                })
            }
        }
        const alert = ({ content: content = "確認操作?", tip: tip = "提示", type: type = "warning" } = { content: "確認操作?", tip: "提示", type: "warning" }) => {
            if(this.status == 'pending'){
                this.content = content;
                this.tip = tip;
                this.type = type;
                this.status = 'alert';
                this.alertFn.forEach(item => {
                    item();
                })
            }
        }
        const promot = ({ content: content = "確認操作?", tip: tip = "提示", type: type = "warning" } = { content: "確認操作?", tip: "提示", type: "warning" }) => {
            if(this.status == 'pending'){
                this.content = content;
                this.tip = tip;
                this.type = type;
                this.status = 'promot';
                this.promotFn.forEach(item => {
                    item();
                })
            }
        }
        fn({confirm,alert,promot})
    }
    
    confirm(callback) {
        MessageBox.confirm(this.content, this.tip, {
            confirmButtonText: "確定",
            cancelButtonText: "取消",
            type: this.type
        }).then(() => {
            callback();
        })
    }
    alert(callback) {
        MessageBox.alert(this.content, this.tip, {
            confirmButtonText: "確定",
            type: this.type,
            callback: () => {
                callback();
            }
        });
    }
    promot(callback) {
        MessageBox.prompt(this.content, this.tip, {
            confirmButtonText: '確定',
            cancelButtonText: '取消',
            type: this.type
        }).then(({ value = '注意promot有個回撥值哦' } = {value: '注意promot有個回撥值哦'}) => {
            callback(value)
        })
    }
    then(callback){
        if(this.status === 'pending'){
            this.confirmFn.push(callback);
            this.alertFn.push(callback);
            this.promotFn.push(callback);
        }
        if(this.status === 'confirm'){
            this.confirm(callback)
        }
        if(this.status === 'alert'){
            this.alert(callback)
        }
        if(this.status === 'promot'){
            this.promot(callback)
        }
    }
}

複製程式碼
  1. 首先建構函式裡面定義顯示的提示,並賦予預設值(畢竟懶,new的時候不想傳參)

  2. 然後先不看三個方法,先看then方法,根據狀態值進入不同的確認提示框

  3. 為什麼定義三個空陣列?因為考慮到可能會有定時器的情況,具體可以看我之前寫的一篇文章:

    【小小前端】手寫一個很簡單的非同步程式設計解決方案Promise及其鏈式呼叫 寫的比較簡單,但基本的內容都解釋了。

最後看一下使用方法,這裡我把類註冊到了Vue的原型上:

confirm

【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

alert

【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

promot

【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

總結

好吧,其實一開始不是這樣寫的,開始的時候思路錯了,最後寫出來也是錯的,然後刪了一半又重新寫,然後不知不覺搞了兩個多小時才想出的這版。

因為原來messagebox已經用了promise了,又封裝了一個類似的,不知道是不是顯得很累贅,不過能少點耦合還是挺好的,如果有不正確的地方希望大家指正。

媽呀,都一點半了,趕緊睡覺!!

【小小前端】瞎搞事——對elementUI中MessageBox 彈框的二次封裝引發的討論

相關文章