|
|
@@ -39,6 +39,10 @@ const handleImageError = (e: Event) => {
|
|
|
const img = e.target as HTMLImageElement;
|
|
|
img.src = "/img/placeholder.png";
|
|
|
};
|
|
|
+
|
|
|
+const handlePreviewError = (e: Event) => {
|
|
|
+ console.error('图片预览加载失败:', e.target);
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
@@ -57,24 +61,30 @@ const handleImageError = (e: Event) => {
|
|
|
@error="handleImageError"
|
|
|
/>
|
|
|
|
|
|
- <!-- 自定义预览弹窗 -->
|
|
|
- <div
|
|
|
- v-if="isPreviewVisible"
|
|
|
- class="image-preview-overlay"
|
|
|
- @click.self="handleClose"
|
|
|
- >
|
|
|
- <div class="preview-content">
|
|
|
- <button class="preview-close" @click="handleClose">×</button>
|
|
|
- <img
|
|
|
- :src="currentImageUrl"
|
|
|
- :alt="alt"
|
|
|
- class="preview-image"
|
|
|
- />
|
|
|
- <div class="preview-actions">
|
|
|
- <span class="image-info">{{ alt || '商品图片' }}</span>
|
|
|
+ <!-- 自定义预览弹窗 - 使用 Teleport 确保渲染到 body -->
|
|
|
+ <Teleport to="body">
|
|
|
+ <transition name="fade">
|
|
|
+ <div
|
|
|
+ v-if="isPreviewVisible"
|
|
|
+ class="image-preview-overlay"
|
|
|
+ @click.self="handleClose"
|
|
|
+ >
|
|
|
+ <div class="preview-content">
|
|
|
+ <button class="preview-close" @click="handleClose">×</button>
|
|
|
+ <img
|
|
|
+ :key="currentImageUrl"
|
|
|
+ :src="currentImageUrl"
|
|
|
+ :alt="alt"
|
|
|
+ class="preview-image"
|
|
|
+ @error="handlePreviewError"
|
|
|
+ />
|
|
|
+ <div class="preview-actions">
|
|
|
+ <span class="image-info">{{ alt || '商品图片' }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ </transition>
|
|
|
+ </Teleport>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -107,7 +117,7 @@ const handleImageError = (e: Event) => {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
- z-index: 3000;
|
|
|
+ z-index: 9999;
|
|
|
animation: fadeIn 0.3s ease;
|
|
|
|
|
|
.preview-content {
|
|
|
@@ -166,6 +176,17 @@ const handleImageError = (e: Event) => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// 过渡动画
|
|
|
+.fade-enter-active,
|
|
|
+.fade-leave-active {
|
|
|
+ transition: opacity 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.fade-enter-from,
|
|
|
+.fade-leave-to {
|
|
|
+ opacity: 0;
|
|
|
+}
|
|
|
+
|
|
|
@keyframes fadeIn {
|
|
|
from {
|
|
|
opacity: 0;
|