vue3.2+ts实现在方法中可调用的拟态框弹窗(类el-MessageBox)

 更新时间:2022年12月14日 16:20:26   作者:Chaplink  
这篇文章主要介绍了vue3.2+ts实现在方法中可调用的拟态框弹窗(类el-MessageBox),这个需求最主要的是要通过方法去调用,为了像el-messagebox使用那样方便,需要的朋友可以参考下

公司UI设计的拟态框弹窗跟Element Plus UI的布局不太一致。导致不能够直接修改样式得到想到样式。直接上图。

这个需求最主要的是要通过方法去调用。为了像el-messagebox使用那样方便。能直接在方法中调用。但这也是难点。去查看了element源码,一个套一个的方法 实在看不懂。因为vue2和vue3的机制改动了。vue2的引用方式不适用了。查找了n篇文章,最终在一篇中找到了一个关键点,也可能是错误的方式,但是能用。

import { createApp } from 'vue'
import MessageBoxVue from './MessageBox.vue' \\你写的拟态框样式
export const MessageBox = (text: any) => {
    return new Promise((resolve, reject) => {
        const capp = createApp(MessageBoxVue, text)
        const container = document.createElement('div')
        const instance = capp.mount(container)
        document.body.insertBefore(container, document.body.firstChild)//插入到body最前面,层级更高
        instance.callback = (val: any) => {
            if (val) {
                resolve(val)
            } else {
                reject()
            }
            capp.unmount()//注销
            document.body.removeChild(container)//点击后清除弹窗
        }
        instance.close = () => {
            capp.unmount()
            document.body.removeChild(container)
        }
    })
}
//重点在这儿
//这边相当于把数据当方法使了。我也不知道什么原理。在上面那边就是能接收到回调。
const cancel = () => {
    callback.value(false)
}
const confirm = () => {
    callback.value(true)
}
const closeBox = () => {
    close.value()
}
//抛出这两个方法?反正这个方法不可或缺。
defineExpose({
    callback,
    close
})
\\这一段是上面的那个messagebox
<template>
    <div ref="MessageBox" class="message-box" :style="[messageBoxWrapperStyleStyle]">
        <div class="message-box-icon">
            <i class="iconfont" :style="`color:${iconColor}`" v-html="iconType"></i>
        </div>
        <div class="message-box-container">
            <div class="message-box-title">{{ title }}</div>
            <div v-if="isHtml" v-html="content"></div>
            <p v-else class="message-box-content">{{ content }}</p>
            <div class="message-box-btn">
                <span v-if="isCancel" class="cancel" @click="cancel">{{ cancelVal }}</span>
                <span v-if="isConfirm" class="confirm" @click="confirm">{{ confirmVal }}</span>
            </div>
        </div>
        <i v-if="closeIcon" class="iconfont cencel-box" @click="closeBox">&#xe618;</i>
    </div>
</template>
<script setup lang="ts">
import { computed, CSSProperties, ref } from 'vue'
const props = defineProps({
    type: {
        type: String,
        default: 'warning'
    },
    title: {
        type: String,
        default: ''
    },
    content: {
        type: String,
        default: ''
    },
    isHtml: {
        type: Boolean,
        default: false
    },
    width: {
        type: Number,
        default: 416
    },
    isCancel: {
        type: Boolean,
        default: true
    },
    cancelVal: {
        type: String,
        default: '取消'
    },
    confirmVal: {
        type: String,
        default: '确定'
    },
    isConfirm: {
        type: Boolean,
        default: true
    },
    closeIcon: {
        type: Boolean,
        default: false
    }
})
const callback = ref()
const close = ref()
const cw = document.documentElement.clientWidth
const ch = document.documentElement.clientHeight
// eslint-disable-next-line vue/return-in-computed-property
const iconType = computed(() => {
    switch (props.type) {
        case 'warning':
            return '&#xe603;'
        case 'info':
            return '&#xe601;'
        case 'error':
            return '&#xe602;'
        case 'success':
            return '&#xe604;'
    }
})
// eslint-disable-next-line vue/return-in-computed-property
const iconColor = computed(() => {
    switch (props.type) {
        case 'warning':
            return '#FF7402'
        case 'info':
            return '#0C64EB'
        case 'error':
            return '#FF4D4F'
        case 'success':
            return '#36B23B'
    }
})
const messageBoxWrapperStyleStyle = computed<CSSProperties>(() => {
    return {
        top: `${ch / 2 - 200 > 200 ? ch / 2 - 200 : 200}px`,
        left: `${cw / 2 - props.width / 2}px`,
        width: `${props.width}px`
    }
})
const cancel = () => {
    callback.value(false)
}
const confirm = () => {
    callback.value(true)
}
const closeBox = () => {
    close.value()
}
defineExpose({
    callback,
    close
})
</script>
<style lang="scss" scoped>
.cencel-box {
    position: absolute;
    top: 15px;
    right: 20px;
    cursor: pointer;
}
.message-box {
    position: absolute;
    border-radius: 5px;
    z-index: 2001;
    display: flex;
    background: #ffffff;
    padding: 20px 20px 20px 32px;
    box-shadow: 0px 0px 20px 0px rgba(6, 0, 1, 0.1);
    .message-box-icon {
        margin-right: 12px;
        line-height: 38px;
        .iconfont {
            font-size: 25px;
        }
    }
    .message-box-container {
        width: calc(100% - 25px);
        .message-box-title {
            font-size: 16px;
            color: #333333;
            line-height: 38px;
        }
        .message-box-content {
            margin: 10px 0px 20px;
            font-size: 14px;
            min-height: 48px;
            color: #999999;
            line-height: 18px;
            // letter-spacing: 0.5px;
        }
    }
    .message-box-btn {
        float: right;
        .cancel {
            height: 32px;
            line-height: 30px;
            display: inline-block;
            text-align: center;
            width: 90px;
            box-sizing: border-box;
            border: 1px solid #d9d9d9;
            border-radius: 3px;
            color: #333333;
            cursor: pointer;
        }
        .cancel:hover {
            color: #0c64eb;
            border-color: #0c64eb;
        }
        .confirm {
            height: 32px;
            width: 90px;
            display: inline-block;
            text-align: center;
            line-height: 32px;
            margin-left: 10px;
            background-color: #0c64eb;
            border-radius: 3px;
            color: #ffffff;
            cursor: pointer;
        }
        .confirm:hover {
            background-color: #2373eb;
        }
    }
}
</style>


引入全局后的调用

// 使用:
// 在main.ts全局引入,也可以按需引入这里展示全局引入
 import {MessageBox} from 'base/src/components/MessageBox/index'
// 注册:
 app.config.globalProperties.$messageBox = MessageBox
// 引用:
 import { getCurrentInstance } from 'vue'
 const { proxy } = getCurrentInstance()
 const fn = ()=>{
     proxy
         .$messageBox({
		 //这边就是传你在MessageBox的props定义的父传子的数据了
             title: '是否确定编辑/删除数据?',
             content: '作业已经发布,如果重新编辑/删除,会清空所有学生 作业提交状态请谨慎操作!'
         })
        .then(() => {
            console.log(1234)
         })
         .catch(() => {
             console.log(12345)
         })
}

到此这篇关于vue3.2+ts实现在方法中可调用的拟态框弹窗(类el-MessageBox)的文章就介绍到这了,更多相关vue3.2+ts实现拟态框弹窗内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue中设置height:100%无效的问题及解决方法

    vue中设置height:100%无效的问题及解决方法

    这篇文章主要介绍了vue中设置height 100%无效的问题及解决方法,需要的朋友可以参考下
    2018-07-07
  • 如何通过Vue3+Element Plus自定义弹出框组件

    如何通过Vue3+Element Plus自定义弹出框组件

    这篇文章主要给大家介绍了关于如何通过Vue3+Element Plus自定义弹出框组件的相关资料,弹窗是前端开发中的一种常见需求,文中通过代码介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-05-05
  • vue实现发送短信倒计时和重发短信功能的示例详解

    vue实现发送短信倒计时和重发短信功能的示例详解

    这篇文章主要给大家介绍了vue实现发送短信倒计时和重发短信功能的相关知识,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • vue实现登陆登出的实现示例

    vue实现登陆登出的实现示例

    本篇文章主要介绍了vue实现登陆登出的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • vue3实现监听store中state状态变化的简单方法

    vue3实现监听store中state状态变化的简单方法

    这篇文章主要给大家介绍了关于vue3实现监听store中state状态变化的简单方法,store是一个状态管理工具,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • 详解vue样式穿透的几种方式

    详解vue样式穿透的几种方式

    本文主要介绍了vue样式穿透的几种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • vue数据push后不能响应式更新的问题

    vue数据push后不能响应式更新的问题

    这篇文章主要介绍了vue数据push后不能响应式更新的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • vue利用sync语法糖实现modal弹框的项目实践

    vue利用sync语法糖实现modal弹框的项目实践

    本文主要介绍了vue利用sync语法糖实现modal弹框的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • vue+canvas实现移动端手写签名

    vue+canvas实现移动端手写签名

    这篇文章主要为大家详细介绍了vue+canvas实现移动端手写签名,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • vue 解决mintui弹窗弹起来,底部页面滚动bug问题

    vue 解决mintui弹窗弹起来,底部页面滚动bug问题

    这篇文章主要介绍了vue 解决mintui弹窗弹起来,底部页面滚动bug问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11

最新评论