qs_xinchun2026_h5/components/ImageGalleryModal.vue

208 lines
4.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import { ref, watch } from 'vue'
// 组件属性
const props = defineProps({
// 是否显示
visible: {
type: Boolean,
default: false
},
// 图片数组
images: {
type: Array,
default: () => []
},
// 当前索引
currentIndex: {
type: Number,
default: 0
}
})
// 组件事件
const emit = defineEmits(['close', 'update:currentIndex'])
// 当前显示的图片索引
const currentImageIndex = ref(props.currentIndex)
// 监听props变化
watch(() => props.currentIndex, (newVal) => {
currentImageIndex.value = newVal
})
watch(() => props.visible, (newVal) => {
if (newVal) {
currentImageIndex.value = props.currentIndex
}
})
// 切换图片
const prevImage = () => {
currentImageIndex.value = (currentImageIndex.value - 1 + props.images.length) % props.images.length
}
const nextImage = () => {
currentImageIndex.value = (currentImageIndex.value + 1) % props.images.length
}
// 关闭弹窗
const closeModal = () => {
emit('close')
}
// 点击遮罩关闭
const handleOverlayClick = () => {
closeModal()
}
</script>
<template>
<div class="gallery-modal" v-if="visible">
<!-- 遮罩层 -->
<div class="modal-overlay" @click="handleOverlayClick"></div>
<!-- 弹窗内容 -->
<div class="modal-content">
<!-- 图片区域 -->
<div class="gallery-image-wrapper">
<img :src="images[currentImageIndex]?.src" :alt="images[currentImageIndex]?.title" class="gallery-image" />
</div>
<!-- 控制区域 -->
<div class="gallery-controls">
<div class="nav-btn prev-btn" @click="prevImage">
<img src="/static/images/btn_prev.png" alt="上一张" class="nav-icon" />
</div>
<div class="gallery-title">{{ images[currentImageIndex]?.title }}</div>
<div class="nav-btn next-btn" @click="nextImage">
<img src="/static/images/btn_next.png" alt="下一张" class="nav-icon" />
</div>
</div>
</div>
<!-- 关闭按钮在对话框外边下方 -->
<div class="close-btn" @click="closeModal">
<img src="/static/images/btn_close.png" alt="关闭" class="close-icon" />
</div>
</div>
</template>
<style scoped>
/* 弹窗容器 */
.gallery-modal {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 1000;
}
/* 遮罩层 */
.modal-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
}
/* 弹窗内容 */
.modal-content {
position: relative;
width: 700rpx;
background-color: #d72717;
border-radius: 20rpx;
padding: 30rpx;
box-sizing: border-box;
z-index: 1001;
animation: modalIn 0.3s ease;
}
@keyframes modalIn {
from {
opacity: 0;
transform: scale(0.9);
}
to {
opacity: 1;
transform: scale(1);
}
}
/* 关闭按钮(在对话框外边下方) */
.close-btn {
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 1001;
margin-top: 30rpx;
}
.close-icon {
width: 100%;
height: 100%;
object-fit: contain;
}
/* 上方图片区域 */
.gallery-image-wrapper {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
}
.gallery-image {
width: 100%;
height: auto;
max-height: 600rpx;
object-fit: contain;
border-radius: 12rpx;
display: block;
}
/* 下方控制区域 */
.gallery-controls {
display: flex;
align-items: center;
justify-content: space-between;
height: 80rpx;
}
.nav-btn {
width: 70rpx;
height: 70rpx;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
flex-shrink: 0;
}
.nav-icon {
width: 100%;
height: 100%;
object-fit: contain;
}
.gallery-title {
flex: 1;
text-align: center;
color: #fff;
font-size: 40rpx;
font-weight: 500;
letter-spacing: 6rpx;
padding: 0 20rpx;
}
</style>