效果图:
可以结合上一篇把放大缩小旋转也加上
// 父组件需要传的参数
companyPreview: {
imgList: [], // 所有图片数组
index: 0, // 当前点击的图片的索引
infinite: true, // 是否可以循环切换
popup: false // 弹窗的显示隐藏
}
预览组件
<template>
<div v-if="previewImg.popup" class="rlPopup">
<div class="close-big-img" @click="close()">
<em class="font_family icon-close-circle"></em>
</div>
<div class="prev handle-btn" v-if="!isSingle" @click="prev()">
<em class="font_family icon-left-line"></em>
</div>
<div class="next handle-btn" v-if="!isSingle" @click="next()">
<em class="font_family icon-right--line"></em>
</div>
<!--缩略图-->
<div class="thumb-wrap">
<ul>
<li
v-for="(img, index) in previewImg.imgList"
:key="img"
:class="{ active:previewImg.index === index}"
@click="showCurrent(index)">
<img :src="img">
</li>
</ul>
</div>
<div class="img-list-wrap">
<div v-for="(img, i) in previewImg.imgList" :key="img">
<img
ref="img"
:src="img"
v-if="i === previewImg.index"
:style="imgStyle">
</div>
</div>
</div>
</template>
<script>
export default {
name: 'PreviewImage',
props: {
previewImg: {
type: Object,
default: () => {}
}
},
data() {
return {
transform: {
scale: 1,
degree: 0
}
}
},
computed: {
isSingle() {
return this.previewImg.imgList.length <= 1
},
isFirst() {
return this.previewImg.index === 0
},
isLast() {
return this.previewImg.index === this.previewImg.imgList.length - 1
},
imgStyle() {
const { scale, degree } = this.transform
const style = {
transform: `scale(${scale}) rotate(${degree}deg)`
}
return style
}
},
methods: {
prev() {
if (this.isFirst && !this.previewImg.infinite) return
if (this.$parent.companyPreview.index >= 0) {
const len = this.previewImg.imgList.length
this.$parent.companyPreview.index = (this.$parent.companyPreview.index - 1 + len) % len
this.reset()
}
},
next() {
if (this.isLast && !this.previewImg.infinite) return
if (this.previewImg.imgList.length > this.$parent.companyPreview.index) {
const len = this.previewImg.imgList.length
this.$parent.companyPreview.index = (this.$parent.companyPreview.index + 1) % len
this.reset()
}
},
reset() {
this.transform = {
scale: 1,
degree: 0
}
},
showCurrent(index) {
this.previewImg.index = index
},
close() {
this.$parent.companyPreview.popup = false
}
}
}
</script>
<style lang="less" scoped>
// 查看大图
.rlPopup {
background: rgba(0,0,0,0.7);
.close-big-img {
position: absolute;
top: 20px;
right: 2%;
z-index: 1000;
em {
cursor: pointer;
color: #ffffff;
font-size: 36px;
}
}
.handle-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 66px;
height: 66px;
line-height: 63px;
color: #fff;
background-color: rgba(0, 0, 0, 0.6);
border-radius: 4px;
cursor: pointer;
text-align: center;
z-index: 10000;
em {
font-size: 50px;
}
}
.prev {
left: 5%;
}
.next {
right: 5%;
}
.img-list-wrap {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
img {
display: block;
object-fit: scale-down;
transition: all 0.3s;
max-width: 800px;
max-height: 600px;
}
}
.thumb-wrap {
position: absolute;
bottom: 2%;
left: 50%;
transform: translateX(-50%);
li {
float: left;
width: 60px;
height: 45px;
border: solid 1px #ececec;
position: relative;
margin-right: 5px;
cursor: pointer;
&:last-child {
margin-right: 0;
}
img {
max-width: 57px;
max-height: 42px;
display: block;
object-fit: scale-down;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
.active {
border-color: #e5242b;
}
}
}
</style>