Skip to content

图片

对话框,一个经常会用到的组件

思路

先写一个messagebox的组件,然后用函数封装一下,函数内容会渲染组件到dom,也会获取组件点击事件结果,用回调函数或者promiss的方式返回给调用的对象,这样使用时用函数调用即可

自定义参数

message:消息内容

title:标题

confirmBtnText:按钮名字:默认确认

图片

新建message_box.vue

html
<template>
    <Teleport to="body">
        <Transition name="message">
            <div class="message-box" ref="openmessage" v-show="isShow">
                <div class="message-box-main">
                    <div class="ombm-title">
                        <span>{{title}}</span><span><i class="bi bi-x" @click="close"></i></span>
                    </div>
                    <div class="ombm-message">{{message}}</div>
                    <div class="ombm-btn">
                        <span class="ombm-btn-confirm" @click="confirm">{{confirmBtnText}}</span>
                    </div>
                </div>
            </div>
        </Transition>
    </Teleport>
</template>

<script>
    export default {
        name: 'Message',
        props: {
            message: {
                type: String,
                default: '这是一条信息'
            },
            title: {
                type: String,
                default: '标题'
            },
            confirmBtnText: {
                type: String,
                default: '确认'
            },
            //确认按钮触发的事件
            onOk: {
                type: Function,
                default: function(value){}
            },
            //关闭按钮触发的事件
            onClose: {
                type: Function,
                default: function(value){}
            }
        },
        data() {
            return {
                isShow: true,
            }
        },
        methods: {
            //关闭
            close(){
                this.isShow = false;
                //触发props:close事件,并返回结果
                this.onClose('close');
            },
            //确认
            confirm(){
                 //触发props:ok事件,并返回结果
                this.isShow = false;
                this.onOk('confirm');
            }
        }

    }
</script>

<style scoped>
    .message-box{
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        background: rgba(0, 0, 0, .5);
        z-index: 99999;
    }
    .message-box-main{
        width: 420px;
        box-shadow: 0px 0px 7px rgba(0, 0, 0, .1);
        background: #ffffff;
        border-radius: 5px;
        padding-bottom: 10px;
    }
    .ombm-title{
        padding: 15px 15px 10px 15px;
        display: flex;
        justify-content: space-between;
        font-size: 18px;
        color: #333333;
    }
    .ombm-title i{
        cursor: pointer;
    }
    .ombm-message{
        padding: 10px 15px;
        font-size: 14px;
        color: #666666;
    }
    .ombm-btn{
        padding: 5px 15px 0px 15px;
        text-align: right;
        cursor: pointer;
    }
    .ombm-btn-confirm{
        display: inline-block;
        padding: 8px 15px;
        font-size: 13px;
        background: #1890ff;
        border-radius: 4px;
        color: #fff;
    }
    .message-enter-active,
    .message-leave-active {
        transition: opacity .3s cubic-bezier(1, 0.5, 0.8, 1);
    }

    .message-enter-from,
    .message-leave-to {
        opacity: 0;
    }
</style>
<template>
    <Teleport to="body">
        <Transition name="message">
            <div class="message-box" ref="openmessage" v-show="isShow">
                <div class="message-box-main">
                    <div class="ombm-title">
                        <span>{{title}}</span><span><i class="bi bi-x" @click="close"></i></span>
                    </div>
                    <div class="ombm-message">{{message}}</div>
                    <div class="ombm-btn">
                        <span class="ombm-btn-confirm" @click="confirm">{{confirmBtnText}}</span>
                    </div>
                </div>
            </div>
        </Transition>
    </Teleport>
</template>

<script>
    export default {
        name: 'Message',
        props: {
            message: {
                type: String,
                default: '这是一条信息'
            },
            title: {
                type: String,
                default: '标题'
            },
            confirmBtnText: {
                type: String,
                default: '确认'
            },
            //确认按钮触发的事件
            onOk: {
                type: Function,
                default: function(value){}
            },
            //关闭按钮触发的事件
            onClose: {
                type: Function,
                default: function(value){}
            }
        },
        data() {
            return {
                isShow: true,
            }
        },
        methods: {
            //关闭
            close(){
                this.isShow = false;
                //触发props:close事件,并返回结果
                this.onClose('close');
            },
            //确认
            confirm(){
                 //触发props:ok事件,并返回结果
                this.isShow = false;
                this.onOk('confirm');
            }
        }

    }
</script>

<style scoped>
    .message-box{
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        background: rgba(0, 0, 0, .5);
        z-index: 99999;
    }
    .message-box-main{
        width: 420px;
        box-shadow: 0px 0px 7px rgba(0, 0, 0, .1);
        background: #ffffff;
        border-radius: 5px;
        padding-bottom: 10px;
    }
    .ombm-title{
        padding: 15px 15px 10px 15px;
        display: flex;
        justify-content: space-between;
        font-size: 18px;
        color: #333333;
    }
    .ombm-title i{
        cursor: pointer;
    }
    .ombm-message{
        padding: 10px 15px;
        font-size: 14px;
        color: #666666;
    }
    .ombm-btn{
        padding: 5px 15px 0px 15px;
        text-align: right;
        cursor: pointer;
    }
    .ombm-btn-confirm{
        display: inline-block;
        padding: 8px 15px;
        font-size: 13px;
        background: #1890ff;
        border-radius: 4px;
        color: #fff;
    }
    .message-enter-active,
    .message-leave-active {
        transition: opacity .3s cubic-bezier(1, 0.5, 0.8, 1);
    }

    .message-enter-from,
    .message-leave-to {
        opacity: 0;
    }
</style>

新建messagebox.js文件

核心文件就是这个,用来传参和渲染组件,还有获取点击事件返回的结果

js
// 引入创建虚拟节点和渲染方法
import { createVNode, render } from "vue";
import messBoxDom from "../components/message_box.vue";

// 参数options是props值,后面加了fn回调方法,如果不想用promise方式获取返回值,也可以用回调方法获取
export default (options,fn) => {
    // 用promise方法,返回插件操作后需要用到的值
    return new Promise((resole,reject)=>{
        let option = options || {};
        // 如果参数不是对象类型,抛出异常,中止程序
        if(typeof option != 'object'){
            throw 'ERROR: MessageBox methods Parameter is not an object ; 报错:MessageBox方法参数不是对象';
            return false;
        }
        //  调用创建虚拟节点方法
        //  第一个参数为要创建的虚拟节点即编写好的vue组件
        //  第二个参数为props的参数
        const vnode = createVNode(messBoxDom,{
            ...option,
            // 点击关闭按钮时触发
            onClose:(value) => {
                // 获取返回值,分别传送给回调函数和promise
                resole(value);
                if(fn){
                    fn(value)
                }
                // 销毁组件
                // 300毫秒留给过渡动画效果
                setTimeout(()=>{
                    render(null, document.body);
                },300)
            },
            onOk:(value) => {
                // 获取返回值,分别传送给回调函数和promise
                resole(value)
                if(fn){
                    fn(value)
                }
                // 销毁组件
                // 300毫秒留给过渡动画效果
                setTimeout(()=>{
                    render(null, document.body);
                },300)
            }
        });
        //  调用渲染方法:将虚拟节点渲染到dom中
        render(vnode, document.body);

    })
   
};
// 引入创建虚拟节点和渲染方法
import { createVNode, render } from "vue";
import messBoxDom from "../components/message_box.vue";

// 参数options是props值,后面加了fn回调方法,如果不想用promise方式获取返回值,也可以用回调方法获取
export default (options,fn) => {
    // 用promise方法,返回插件操作后需要用到的值
    return new Promise((resole,reject)=>{
        let option = options || {};
        // 如果参数不是对象类型,抛出异常,中止程序
        if(typeof option != 'object'){
            throw 'ERROR: MessageBox methods Parameter is not an object ; 报错:MessageBox方法参数不是对象';
            return false;
        }
        //  调用创建虚拟节点方法
        //  第一个参数为要创建的虚拟节点即编写好的vue组件
        //  第二个参数为props的参数
        const vnode = createVNode(messBoxDom,{
            ...option,
            // 点击关闭按钮时触发
            onClose:(value) => {
                // 获取返回值,分别传送给回调函数和promise
                resole(value);
                if(fn){
                    fn(value)
                }
                // 销毁组件
                // 300毫秒留给过渡动画效果
                setTimeout(()=>{
                    render(null, document.body);
                },300)
            },
            onOk:(value) => {
                // 获取返回值,分别传送给回调函数和promise
                resole(value)
                if(fn){
                    fn(value)
                }
                // 销毁组件
                // 300毫秒留给过渡动画效果
                setTimeout(()=>{
                    render(null, document.body);
                },300)
            }
        });
        //  调用渲染方法:将虚拟节点渲染到dom中
        render(vnode, document.body);

    })
   
};

调用

html
import MessageBox from '../plugin/js/message_box.js'
<button  @click="onMessagebox" type="primary">点击</button>

onMessagebox(){
    MessageBox()
}
import MessageBox from '../plugin/js/message_box.js'
<button  @click="onMessagebox" type="primary">点击</button>

onMessagebox(){
    MessageBox()
}

运行结果

图片 修改参数,并用回调函数的方式获取点击事件反馈的结果

js
onMessagebox(){
    MessageBox({
        title: '哈哈系统提示',
        message: '我们的任务就是从周一笑到周七'
    },
    (res)=>{
        console.log(res)
    })
},
onMessagebox(){
    MessageBox({
        title: '哈哈系统提示',
        message: '我们的任务就是从周一笑到周七'
    },
    (res)=>{
        console.log(res)
    })
},

运行结果

图片 控制台成功打印出结果

再修改代码。用promise的方式获取结果

js
onMessagebox(){
    MessageBox({
        title: '哈哈系统提示',
        message: '我们的任务就是从周一笑到周七'
    }).then(res=>{
        console.log(res)
    })
}
onMessagebox(){
    MessageBox({
        title: '哈哈系统提示',
        message: '我们的任务就是从周一笑到周七'
    }).then(res=>{
        console.log(res)
    })
}

运行结果

图片 promise的方式也正常获取

扩展部分:

添加返回按钮,或者配置props参数,控制隐藏显示按钮。

本文到此结束。

反馈信息

INFO

邮箱: open_teams@163.com