vue3 封装 Dialog 弹窗组件,支持返回promise
Dialog .vue
<template>
<div class="dialog-wrap">
<div class="dialog-wrap-body">
<div class="dialog-wrap-body-title">{{ title }}</div>
<div class="dialog-wrap-body-content"> {{ content }} </div>
<div class="dialog-wrap-body-footer">
<div v-if="showCancel" class="cancel" @click="handleCancel" :style="{ color: cancelColor }">{{ cancelText }}
</div>
<div v-if="showConfirm" class="confirm" @click="handleSuccess" :style="{ color: confirmColor }">{{ confirmText
}}
</div>
</div>
</div>
</div>
</template>
<script setup>
defineProps({
title: String,
content: String,
showConfirm: Boolean,
confirmText: String,
confirmColor: String,
showCancel: Boolean,
cancelText: String,
cancelColor: String,
handleSuccess: Function,
handleCancel: Function
})
</script>
<style lang="less" scoped>
.dialog-wrap {
position: fixed !important;
top: 0;
height: 100vh;
left: 0;
width: 100vw;
z-index: 3000;
background-color: rgba(0, 0, 0, .4);
display: flex;
align-items: center;
justify-content: center;
touch-action: none;
&-body {
min-height: 400px;
width: 80%;
max-width: 750px;
background: #fff;
border-radius: 8px;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
color: #313131;
&-title {
min-height: 90px;
padding: 0 20px;
display: flex;
align-items: center;
font-size: 36px;
font-weight: 600;
}
&-content {
flex: 1;
min-height: 140px;
padding: 20px;
font-size: 30px;
line-height: 36px;
box-sizing: border-box;
display: flex;
align-items: center;
}
&-footer {
width: 100%;
height: 90px;
display: flex;
align-items: center;
justify-content: space-between;
border-top: 2px solid #e6e6e6;
>div {
flex: 1;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
font-size: 32px;
font-weight: bold;
&:last-child::before {
content: ' ';
display: inline-block;
position: absolute;
left: 0;
height: 100%;
width: 2px;
background: #e6e6e6;
}
}
}
}
}
</style>
index.js
import { createApp } from 'vue'
import Dialog from './Dialog.vue'
export default {
instance: null,
parent: document.createElement('div'),
clear () {
if (this.instance !== null) {
this.instance.unmount(this.parent)
document.body.removeChild(this.parent)
this.instance = null
}
},
/**
* 支持 返回 Promise
* @param {*} options
* @returns
*/
showDialog (options) {
if (this.instance !== null) this.clear()
return new Promise(resolve => {
if (!options) {
if (isCallback(options.fail)) {
options.fail()
}
throw new Error('调用错误')
}
const _this = this
const defaultOptions = {
title: '提示',
content: '内容',
showConfirm: true,
confirmText: '确定',
confirmColor: '#7127be',
showCancel: true,
cancelText: '取消',
cancelColor: '#999999',
handleSuccess: () => {
if (isCallback(options.success)) {
const res = { confirm: true }
options.success(res)
resolve(res)
}
},
handleCancel: () => {
if (isCallback(options.success)) {
const res = { cancel: true }
options.success(res)
resolve(res)
}
}
}
function isCallback (callback) {
_this.clear()
if (callback && typeof callback === 'function') {
return true
}
return false
}
Object.assign(defaultOptions, options)
console.log(defaultOptions)
this.instance = createApp(Dialog, defaultOptions)
document.body.appendChild(this.parent)
this.instance.mount(this.parent)
})
},
}
//调用
import * as utils from './index.js'
utils.showDialog({title:"title",content:"content",success:({confirm,cancel})=>{console.log(confirm,cancel)}})
utils.showDialog({title:"title",content:"content"}).then(({confirm,cancel})=>{console.log(confirm,cancel)})