【小小前端】瞎搞事——对elementUI中MessageBox 弹框的二次封装引发的讨论

4,745 阅读3分钟

前言

最近公司项目比较忙,导致之前的排序没时间更新,等后面有空再继续。

如题所述,各位大佬平时项目中肯定针对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('是的没错,回调写在这里就行了')
})

毫无疑问的结果:

个人魔改版

在封装代码的时候突然想到之前写过一个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

alert

promot

总结

好吧,其实一开始不是这样写的,开始的时候思路错了,最后写出来也是错的,然后删了一半又重新写,然后不知不觉搞了两个多小时才想出的这版。

因为原来messagebox已经用了promise了,又封装了一个类似的,不知道是不是显得很累赘,不过能少点耦合还是挺好的,如果有不正确的地方希望大家指正。

妈呀,都一点半了,赶紧睡觉!!