176 lines
3.6 KiB
Vue
176 lines
3.6 KiB
Vue
<!--
|
||
* @author wangzhuo
|
||
* @date 2025/9/18 10:30
|
||
* @description 模态弹窗组件(支持点击蒙层关闭、支持换行显示内容)
|
||
-->
|
||
<template>
|
||
<view class="model" v-if="modelValue" @click="handleClose" @touchmove.prevent @mousewheel.prevent>
|
||
<view v-if="closeTip" style="color:rgba(255,255,255,0.15); letter-spacing: 5rpx; margin-top: 50%;text-align: center">{{closeTip}}</view>
|
||
<view class="model-con" @click.stop>
|
||
<view class="model-top" v-if="title">{{ title }}</view>
|
||
<view :class="{'model-middle': true,'m-height': !title, 'align-center': contentAlign==='center'}">
|
||
<view v-for="text in content.split('\n')">{{text}}</view>
|
||
</view>
|
||
<view class="model-bottom">
|
||
<button v-if="cancelBtn" type="primary" class="btn-cancel" @click="handleCancel">{{ cancelText }}</button>
|
||
<button v-if="confirmBtn" type="default" class="btn-green" @click="handleConfirm" :loading="loading"
|
||
:disabled="loading">{{ confirmText }}
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {ref} from 'vue'
|
||
|
||
const props = defineProps({
|
||
modelValue: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
closeTip: {
|
||
type: String,
|
||
default: "点按空白处取消",
|
||
},
|
||
title: {
|
||
type: String,
|
||
},
|
||
content: {
|
||
type: String
|
||
},
|
||
contentAlign: {
|
||
type: String
|
||
},
|
||
cancelBtn: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
confirmBtn: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
cancelText: {
|
||
type: String,
|
||
default: '取消'
|
||
},
|
||
confirmText: {
|
||
type: String,
|
||
default: '确认'
|
||
}
|
||
})
|
||
|
||
let loading = ref(false);
|
||
|
||
// 调用父组件的方法
|
||
const emit = defineEmits(['update:modelValue', 'cancel', 'confirm', 'success'])
|
||
|
||
// 点击蒙层关闭模态窗
|
||
const handleClose = () => {
|
||
emit('update:modelValue', false);
|
||
}
|
||
|
||
const handleCancel = () => {
|
||
emit('cancel');
|
||
emit('success', 'cancel')
|
||
handleClose();
|
||
}
|
||
|
||
const handleConfirm = () => {
|
||
emit('confirm');
|
||
emit('success', 'confirm')
|
||
handleClose();
|
||
}
|
||
|
||
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.model {
|
||
position: fixed;
|
||
top: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
left: 0;
|
||
background: rgba(0, 0, 0, 0.4);
|
||
z-index: 9999;
|
||
|
||
.model-con {
|
||
background: #fff;
|
||
position: fixed;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
top: 50%;
|
||
left: 50%;
|
||
width: 500rpx;
|
||
min-height: 278rpx;
|
||
margin-left: -270rpx;
|
||
margin-top: -139rpx;
|
||
border-radius: 24rpx;
|
||
padding: 20rpx 30rpx;
|
||
}
|
||
|
||
.model-top {
|
||
text-align: center;
|
||
padding: 20rpx 0;
|
||
font-size: 36rpx;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.model-middle {
|
||
// margin-top:290rpx;
|
||
text-align: start;
|
||
font-size: 30rpx;
|
||
//line-height: 42rpx;
|
||
color: #333333;
|
||
|
||
.font-green {
|
||
color: #05A3F4;
|
||
font-size: 42rpx;
|
||
font-weight: bold;
|
||
padding: 20rpx 0;
|
||
}
|
||
}
|
||
|
||
.align-center{
|
||
text-align: center;
|
||
}
|
||
|
||
.m-height {
|
||
padding-top: 28rpx;
|
||
}
|
||
|
||
.model-bottom {
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 30rpx 0 20rpx;
|
||
// align-items: center;
|
||
.btn-green, .btn-cancel {
|
||
background-color: #fff;
|
||
color: #05A3F4;
|
||
border-radius: 48rpx;
|
||
width: 200rpx;
|
||
height: 65rpx;
|
||
line-height: 60rpx;
|
||
text-align: center;
|
||
font-size: 30rpx;
|
||
border: 1px solid #05A3F4;
|
||
margin-left: 0rpx !important;
|
||
margin-right: 0 !important;
|
||
|
||
&::after {
|
||
border: none;
|
||
border-radius: 37rpx;
|
||
}
|
||
}
|
||
|
||
.btn-green {
|
||
border: 1px solid #05A3F4;
|
||
background-color: #05A3F4;
|
||
color: #fff;
|
||
margin-left: 20rpx !important;
|
||
}
|
||
}
|
||
}
|
||
</style> |