181 lines
3.4 KiB
Vue
181 lines
3.4 KiB
Vue
|
|
<template>
|
|||
|
|
<transition name="popup-fade">
|
|||
|
|
<div class="global-popup" v-show="visible">
|
|||
|
|
<!-- 遮罩层 -->
|
|||
|
|
<div class="popup-mask" @click="maskClose && handleClose"></div>
|
|||
|
|
<!-- 弹窗主体 -->
|
|||
|
|
<div class="popup-main" :style="{ width: width + 'px' }">
|
|||
|
|
<!-- 标题 -->
|
|||
|
|
<div class="popup-title" v-if="title">{{ title }}</div>
|
|||
|
|
<!-- 自定义内容插槽 -->
|
|||
|
|
<slot name="content"></slot>
|
|||
|
|
<!-- 默认内容 -->
|
|||
|
|
<div class="popup-content" v-if="!$slots.content">{{ content }}</div>
|
|||
|
|
<!-- 底部按钮 -->
|
|||
|
|
<div class="popup-footer" v-if="showBtn">
|
|||
|
|
<button class="btn cancel" @click="handleCancel" v-if="showCancelBtn">
|
|||
|
|
{{ cancelText }}
|
|||
|
|
</button>
|
|||
|
|
<button class="btn confirm" @click="handleConfirm">
|
|||
|
|
{{ confirmText }}
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</transition>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
export default {
|
|||
|
|
name: "GlobalPopup",
|
|||
|
|
props: {
|
|||
|
|
// 是否显示弹窗
|
|||
|
|
visible: {
|
|||
|
|
type: Boolean,
|
|||
|
|
default: false,
|
|||
|
|
},
|
|||
|
|
// 弹窗标题
|
|||
|
|
title: {
|
|||
|
|
type: String,
|
|||
|
|
default: "",
|
|||
|
|
},
|
|||
|
|
// 弹窗内容
|
|||
|
|
content: {
|
|||
|
|
type: String,
|
|||
|
|
default: "",
|
|||
|
|
},
|
|||
|
|
// 弹窗宽度(px)
|
|||
|
|
width: {
|
|||
|
|
type: [Number, String],
|
|||
|
|
default: 300,
|
|||
|
|
},
|
|||
|
|
// 是否显示按钮
|
|||
|
|
showBtn: {
|
|||
|
|
type: Boolean,
|
|||
|
|
default: true,
|
|||
|
|
},
|
|||
|
|
// 是否显示取消按钮
|
|||
|
|
showCancelBtn: {
|
|||
|
|
type: Boolean,
|
|||
|
|
default: true,
|
|||
|
|
},
|
|||
|
|
// 取消按钮文字
|
|||
|
|
cancelText: {
|
|||
|
|
type: String,
|
|||
|
|
default: "取消",
|
|||
|
|
},
|
|||
|
|
// 确认按钮文字
|
|||
|
|
confirmText: {
|
|||
|
|
type: String,
|
|||
|
|
default: "确认",
|
|||
|
|
},
|
|||
|
|
// 点击遮罩是否关闭
|
|||
|
|
maskClose: {
|
|||
|
|
type: Boolean,
|
|||
|
|
default: true,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
// 通用关闭方法
|
|||
|
|
handleClose() {
|
|||
|
|
this.$emit("update:visible", false);
|
|||
|
|
},
|
|||
|
|
// 取消按钮回调
|
|||
|
|
handleCancel() {
|
|||
|
|
this.handleClose();
|
|||
|
|
this.$emit("cancel");
|
|||
|
|
},
|
|||
|
|
// 确认按钮回调
|
|||
|
|
handleConfirm() {
|
|||
|
|
this.handleClose();
|
|||
|
|
this.$emit("confirm");
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped>
|
|||
|
|
/* Vue2 过渡动画类名 */
|
|||
|
|
.popup-fade-enter,
|
|||
|
|
.popup-fade-leave-to {
|
|||
|
|
opacity: 0;
|
|||
|
|
}
|
|||
|
|
.popup-fade-enter-active,
|
|||
|
|
.popup-fade-leave-active {
|
|||
|
|
transition: all 0.3s ease;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 弹窗容器:固定定位+居中 */
|
|||
|
|
.global-popup {
|
|||
|
|
position: fixed;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
right: 0;
|
|||
|
|
bottom: 0;
|
|||
|
|
z-index: 9999; /* 高层级保证不被覆盖 */
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 遮罩层 */
|
|||
|
|
.popup-mask {
|
|||
|
|
position: absolute;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
right: 0;
|
|||
|
|
bottom: 0;
|
|||
|
|
background: rgba(0, 0, 0, 0.5);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 弹窗主体 */
|
|||
|
|
.popup-main {
|
|||
|
|
background: #fff;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
padding: 16px;
|
|||
|
|
position: relative;
|
|||
|
|
z-index: 1;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 标题样式 */
|
|||
|
|
.popup-title {
|
|||
|
|
font-size: 18px;
|
|||
|
|
font-weight: bold;
|
|||
|
|
text-align: center;
|
|||
|
|
margin-bottom: 16px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 内容样式 */
|
|||
|
|
.popup-content {
|
|||
|
|
font-size: 14px;
|
|||
|
|
line-height: 1.5;
|
|||
|
|
margin-bottom: 24px;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 底部按钮容器 */
|
|||
|
|
.popup-footer {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 按钮样式 */
|
|||
|
|
.btn {
|
|||
|
|
padding: 8px 16px;
|
|||
|
|
border: none;
|
|||
|
|
border-radius: 4px;
|
|||
|
|
font-size: 14px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
flex: 1;
|
|||
|
|
margin: 0 4px;
|
|||
|
|
}
|
|||
|
|
.cancel {
|
|||
|
|
background: #f5f5f5;
|
|||
|
|
color: #333;
|
|||
|
|
}
|
|||
|
|
.confirm {
|
|||
|
|
background: #007aff;
|
|||
|
|
color: #fff;
|
|||
|
|
}
|
|||
|
|
</style>
|