<template>
|
<div v-if="visible" class="custom-image-viewer">
|
<!-- 遮罩层 -->
|
<div class="el-image-viewer__mask" @click.self="handleMaskClick"></div>
|
|
<!-- 图片预览主体 -->
|
<div class="el-image-viewer__btn el-image-viewer__close" @click="close">
|
<i class="el-icon-close"></i>
|
</div>
|
|
<!-- 上一张按钮 -->
|
<div
|
class="el-image-viewer__btn el-image-viewer__prev"
|
:class="{ 'is-disabled': isFirst }"
|
@click="goPrev"
|
>
|
<i class="el-icon-arrow-left"></i>
|
</div>
|
|
<!-- 下一张按钮 -->
|
<div
|
class="el-image-viewer__btn el-image-viewer__next"
|
:class="{ 'is-disabled': isLast }"
|
@click="goNext"
|
>
|
<i class="el-icon-arrow-right"></i>
|
</div>
|
|
<!-- 图片展示 -->
|
<div class="el-image-viewer__canvas">
|
<img
|
v-if="currentUrl"
|
:src="currentUrl"
|
:key="currentIndex"
|
@error="handleError"
|
class="el-image-viewer__img"
|
/>
|
</div>
|
|
<!-- 自定义提示信息 -->
|
<div v-if="showTip" class="custom-viewer-tip">
|
{{ tipMessage }}
|
</div>
|
</div>
|
</template>
|
|
<script>
|
export default {
|
name: 'CustomImageViewer',
|
props: {
|
urlList: {
|
type: Array,
|
default: () => []
|
},
|
initialIndex: {
|
type: Number,
|
default: 0
|
},
|
visible: {
|
type: Boolean,
|
default: false
|
}
|
},
|
data() {
|
return {
|
currentIndex: this.initialIndex,
|
showTip: false,
|
tipMessage: ''
|
};
|
},
|
computed: {
|
currentUrl() {
|
return this.urlList[this.currentIndex];
|
},
|
isFirst() {
|
return this.currentIndex === 0;
|
},
|
isLast() {
|
return this.currentIndex === this.urlList.length - 1;
|
}
|
},
|
watch: {
|
initialIndex(newVal) {
|
this.currentIndex = newVal;
|
},
|
visible(newVal) {
|
if (!newVal) {
|
this.showTip = false;
|
this.tipMessage = '';
|
}
|
}
|
},
|
methods: {
|
close() {
|
this.$emit('update:visible', false);
|
this.$emit('close');
|
},
|
handleMaskClick() {
|
this.close();
|
},
|
goPrev() {
|
if (this.isFirst) {
|
this.showTipMessage('这已经是第一张了');
|
return;
|
}
|
this.currentIndex--;
|
this.hideTip();
|
},
|
goNext() {
|
if (this.isLast) {
|
this.showTipMessage('这已经是最后一张了');
|
return;
|
}
|
this.currentIndex++;
|
this.hideTip();
|
},
|
showTipMessage(message) {
|
this.tipMessage = message;
|
this.showTip = true;
|
// 2秒后自动隐藏提示
|
setTimeout(() => {
|
this.hideTip();
|
}, 2000);
|
},
|
hideTip() {
|
this.showTip = false;
|
this.tipMessage = '';
|
},
|
handleError() {
|
console.error(`图片加载失败: ${this.currentUrl}`);
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.custom-image-viewer {
|
position: fixed;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
left: 0;
|
z-index: 2000; /* 确保 z-index 足够高 */
|
}
|
|
.el-image-viewer__mask {
|
position: absolute;
|
width: 100%;
|
height: 100%;
|
background-color: rgba(0, 0, 0, 0.5);
|
}
|
|
.el-image-viewer__btn {
|
position: absolute;
|
z-index: 1;
|
color: #fff;
|
background-color: rgba(0, 0, 0, 0.3);
|
border-radius: 50%;
|
width: 40px;
|
height: 40px;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
cursor: pointer;
|
user-select: none;
|
}
|
|
.el-image-viewer__btn.is-disabled {
|
cursor: not-allowed;
|
opacity: 0.5;
|
}
|
|
.el-image-viewer__close {
|
top: 20px;
|
right: 20px;
|
}
|
|
.el-image-viewer__prev {
|
left: 20px;
|
top: 50%;
|
transform: translateY(-50%);
|
}
|
|
.el-image-viewer__next {
|
right: 20px;
|
top: 50%;
|
transform: translateY(-50%);
|
}
|
|
.el-image-viewer__canvas {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
height: 100%;
|
}
|
|
.el-image-viewer__img {
|
max-width: 90%;
|
max-height: 90%;
|
object-fit: contain;
|
}
|
|
.custom-viewer-tip {
|
position: absolute;
|
bottom: 50px;
|
left: 50%;
|
transform: translateX(-50%);
|
background-color: rgba(0, 0, 0, 0.7);
|
color: #fff;
|
padding: 10px 20px;
|
border-radius: 4px;
|
z-index: 2001;
|
}
|
</style>
|