一、效果图

二、代码
mydialog.vue
<template>
<div class="vux-x-dialog">
<transition :name="maskTransition">
<div class="weui-mask" @click.self="hide" v-show="show" :style="maskStyle">
<transition :name="dialogTransition">
<div :class="dialogClass" v-show="show" :style="dialogStyle">
<slot></slot>
</div>
</transition>
</div>
</transition>
</div>
</template>
<script>
export default {
name: 'x-dialog',
model: {
prop: 'show',
event: 'change'
},
props: {
show: {
type: Boolean,
default: false
},
maskTransition: {
type: String,
default: 'vux-mask'
},
maskZIndex: [String, Number],
dialogTransition: {
type: String,
default: 'vux-dialog'
},
dialogClass: {
type: String,
default: 'weui-dialog'
},
hideOnBlur: Boolean,
dialogStyle: Object
},
computed: {
maskStyle() {
if (typeof this.maskZIndex !== 'undefined') {
return {
zIndex: this.maskZIndex
}
}
}
},
mounted() {
},
watch: {
show(val) {
this.$emit('update:show', val)
this.$emit(val ? 'on-show' : 'on-hide')
}
},
methods: {
hide() {
if (this.hideOnBlur) {
this.$emit('update:show', false)
}
}
},
data() {
return {
}
}
}
</script>
<style scoped>
.weui-dialog {
position: fixed;
display: table;
z-index: 5000;
width: 80%;
max-width: 300px;
margin: auto;
background-color: #fff;
text-align: center;
border-radius: 3px;
overflow: hidden;
}
.weui-mask .weui-dialog {
position: relative;
}
.weui-mask {
position: fixed;
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0, 0, 0, .6);
}
.vux-x-dialog .weui-mask {
background: rgba(0, 0, 0, .5);
position: fixed;
z-index: 1000;
}
.weui-mask_transparent {
position: fixed;
z-index: 1000;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
.vux-fade-enter-active,
.vux-fade-leave-active {
opacity: 1;
transition: opacity linear 0.2s;
}
.vux-fade-enter,
.vux-fade-leave-to {
opacity: 0;
}
.vux-dialog-enter-active {
animation: vux-dialog-in .5s;
}
.vux-dialog-leave-active {
animation: vux-dialog-out .3s;
}
@keyframes vux-dialog-in {
0% {
transform: scale(1.185);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
}
}
@keyframes vux-dialog-out {
0% {
transform: scale(1);
opacity: 1;
}
100% {
transform: scale(0.85);
opacity: 0;
}
}
.vux-mask-enter,
.vux-mask-leave-active {
opacity: 0;
}
.vux-mask-leave-active,
.vux-mask-enter-active {
transition: opacity 300ms;
}
</style>
三、使用
import XDialog from '@/components/MyDialog.vue';
const isshow = ref(false)
const handleShowUpdate = (val) => {
isshow.value = val
}
const dShow = () => {
alert('show')
}
const dHide = () => {
alert('hide')
}
<x-dialog :show="isshow" :dialogStyle="{width: '27rem', maxWidth: '27rem', borderRadius: '8px'}" :hideOnBlur="true" @update:show="handleShowUpdate" @on-show="dShow" @on-hide="dHide">
123
</x-dialog>