feat: 自定义模态弹窗组件(支持蒙层触摸关闭、文本换行显示)
This commit is contained in:
169
src/components/closeableModal.vue
Normal file
169
src/components/closeableModal.vue
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
<!--
|
||||||
|
* @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}">
|
||||||
|
<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
|
||||||
|
},
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.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>
|
||||||
Reference in New Issue
Block a user