一般的可以用element-ui的Image来实现图片预览
但是如果是鼠标移上去在卡片上才出现图片并且需要预览,element会有一些bug,所以自己写一个
效果图:带切换,放大缩小旋转

// 父组件需要传的参数
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="zoom-wrap">
<i @click="handleActions('zoomOut')" class="el-icon-zoom-out"></i>
<i @click="handleActions('zoomIn')" class="el-icon-zoom-in"></i>
<i @click="handleActions('left')" class="el-icon-refresh-left"></i>
<i @click="handleActions('right')" class="el-icon-refresh-right"></i>
</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"
alt="">
</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()
}
},
handleActions(action) {
const { zoomRate, rotateDeg, enableTransition } = {
zoomRate: 0.2,
rotateDeg: 90,
enableTransition: true
}
const { transform } = this
switch (action) {
case 'zoomOut':
if (transform.scale > 0.2) {
transform.scale = parseFloat((transform.scale - zoomRate).toFixed(3))
}
break
case 'zoomIn':
transform.scale = parseFloat((transform.scale + zoomRate).toFixed(3))
break
case 'left':
transform.degree -= rotateDeg
break
case 'right':
transform.degree += rotateDeg
break
}
transform.enableTransition = enableTransition
},
reset() {
this.transform = {
scale: 1,
degree: 0
}
},
close() {
this.$parent.companyPreview.popup = false
}
}
}
</script>
<style lang="less" scoped>
// 查看大图
.rlPopup {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 999;
.close-big-img {
position: absolute;
top: 20px;
right: 5%;
z-index: 10000;
em {
cursor: pointer;
color: #ffffff;
font-size: 36px;
}
}
.handle-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 44px;
height: 44px;
line-height: 38px;
font-size: 24px;
color: #fff;
background-color: #606266;
border-color: #fff;
border-radius: 50%;
cursor: pointer;
text-align: center;
z-index: 10000;
}
.prev {
left: 40px;
}
.next {
right: 40px;
}
.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;
width: 480px;
height: 320px;
}
}
.zoom-wrap {
position: absolute;
bottom: 16px;
left: 50%;
transform: translateX(-50%);
background-color: #606266;
border-radius: 22px;
z-index: 10000;
width: 222px;
height: 44px;
line-height: 47px;
padding: 0 23px;
i {
color: #ffffff;
cursor: pointer;
font-size: 22px;
margin-right: 25px;
&:last-child {
margin-right: 0;
}
}
}
}
</style>
网友评论