自己封装的图片预览组件

自己封装的定制化图片预览组件

1、针对Vue2,
2、支持图片列表切换、图片的旋转、放大、缩小、全屏
3、定制化:显示当前图片的名称,样式自定义

0、效果图

在这里插入图片描述

一、图片预览组件

<template>
    <div class="image-preview-box"  :style="{
        top:`${imagePreviewBox.top}%`,
        right: `${imagePreviewBox.right}%`,
        left: `${imagePreviewBox.left}%`,
        bottom: `${imagePreviewBox.bottom}%`
    }">
        <!-- 图片预览封装 带图片名称的   -->
        <div class="tit-box">
            <!-- 中间名称  -->
            <div class="center-tit">{{currentImageName}}</div>
            <!-- 右边的关闭按钮  -->
            <div class="right-close-icon image-viewer__btn" @click="closePreviewBox">X</div>
        </div>
        <!-- 图片预览盒子  -->
        <div class="image-preview-list-box">
            <!-- 图片预览列表  -->
            <ul  class="image-preview-list">
                <li>
                    <!--  易错点: :style="{transform: `rotateZ(${currentImageRotateZ}deg)`}"  -->
                    <img :style="{transform: `rotateZ(${currentImageRotateZ}deg)`}" ref="imagePreviewList" :src="currentImageSrc" alt="">
                </li>
            </ul>
            <!-- 切换 按钮  -->
            <div @click="arrowFn('left')" class="left-arrow image-viewer__btn"><a-icon type="left" /></div>
            <div @click="arrowFn('right')" class="right-arrow image-viewer__btn"><a-icon type="right" /></div>
        </div>
        <!-- 操作图片盒子  -->
        <div class="image-viewer__actions image-viewer__btn">
            <div class="image-viewer__actions__inner">
                <!-- 放小镜  -->
                <a-icon title="缩小" @click="zoomFn('out')" type="zoom-out" />
                <!-- 放大镜  -->
                <a-icon title="放大" @click="zoomFn('in')" type="zoom-in" />
                <!-- 全屏 缩小:<a-icon type="fullscreen-exit" /> -->
                <a-icon :title="isFullscreen === 'fullscreen-exit' ? '小屏' : '全屏'" @click="zoomFn(isFullscreen)" :type="isFullscreen" />
                <!-- 向左旋转  -->
                <a-icon title="左旋转" @click="zoomFn('undo')" type="undo" />
                <!-- 向右旋转  -->
                <a-icon title="右旋转" @click="zoomFn('redo')" type="redo" />
            </div>
        </div>
    </div>
</template>

<script>
export default {
    props : ["currentPreviewId"],
    data() {
        return {
            currentImageIndex : 0,    // 当前图片的索引
            currentImageSrc : "",  // 保存当前图片
            currentImageName : "",  // 保存当前图片名称
            isFullscreen : "fullscreen",
            currentImageRotateZ : 0,  // 保存图片的旋转角度
            imagePreviewBox : {   // 保存预览盒子的大小
                top:24,
                right: 16.5,
                left: 16.5,
                bottom: 9
            }
        }
    },
    watch : {
        currentPreviewId : {
            handler(newCurrentPreviewImgId) {
                if(newCurrentPreviewImgId) {
                    // savePreviewImg
                    this.$parent.savePreviewImg.forEach((item,index)=>{
                        if(item.id === newCurrentPreviewImgId) {
                            this.currentImageIndex = index;
                            // this.currentImageSrc = item.coverUrl;
                            // this.currentImageName = item.fileName.slice(0,item.fileName.lastIndexOf('.'));
                            return;
                        }
                    })
                }
            },
            immediate : true
        },
        currentImageIndex : {
           handler() {
            this.currentImageSrc = this.$parent.savePreviewImg[this.currentImageIndex].coverUrl;
            this.currentImageName = this.$parent.savePreviewImg[this.currentImageIndex].fileName.slice(0,this.$parent.savePreviewImg[this.currentImageIndex].fileName.lastIndexOf('.'));
           },
           immediate : true
        }
    },
    methods: {
        // 操作预览图片
        zoomFn(msg) {
            switch(msg) {
                // 放小镜
                case "out" :
                    this.imagePreviewBox.top >= 24 ? this.imagePreviewBox.top = 24 : this.imagePreviewBox.top += 6;
                    this.imagePreviewBox.right >= 3.2 ? this.imagePreviewBox.right = 16.5 : this.imagePreviewBox.right += 3.2;
                    this.imagePreviewBox.left >= 3.2 ? this.imagePreviewBox.left = 16.5 : this.imagePreviewBox.left += 3.2;
                    this.imagePreviewBox.bottom >= 9 ? this.imagePreviewBox.bottom = 9 : this.imagePreviewBox.bottom += 2.4;
                    this.isFullscreen = "fullscreen";
                    break; 
                // 放大镜
                case "in" : 
                    this.imagePreviewBox.top <= 0 ? this.imagePreviewBox.top = 0 : this.imagePreviewBox.top -= 6;
                    this.imagePreviewBox.right <= 3.2 ? this.imagePreviewBox.right = 0 : this.imagePreviewBox.right -= 3.2;
                    this.imagePreviewBox.left <= 3.2 ? this.imagePreviewBox.left = 0 : this.imagePreviewBox.left -= 3.2;
                    this.imagePreviewBox.bottom <= 0 ? this.imagePreviewBox.bottom = 0 : this.imagePreviewBox.bottom -= 2.4;
                    
                    this.isFullscreen = this.imagePreviewBox.top === 0 && this.imagePreviewBox.right === 0 && this.imagePreviewBox.bottom === 0 ? "fullscreen-exit" : "fullscreen";
                    break;
                // 小屏 切到 大屏
                case "fullscreen" :
                    this.isFullscreen = "fullscreen-exit";
                    this.imagePreviewBox = {
                        top : 0,
                        left : 0,
                        right : 0,
                        bottom : 0
                    };
                    break;
                // 退出全屏
                case "fullscreen-exit" : 
                    this.isFullscreen = "fullscreen";
                    this.imagePreviewBox = {
                        top : 24,
                        left : 16.5,
                        right : 16.5,
                        bottom : 9
                    };
                    break;
                // 左旋转 transform: rotateZ('angle');
                case "undo" :
                    this.currentImageRotateZ === -360 ? this.currentImageRotateZ = 0 : this.currentImageRotateZ -= 90;
                    break;
                // 右旋转
                case "redo" : 
                    this.currentImageRotateZ === 360 ? this.currentImageRotateZ = 0 : this.currentImageRotateZ += 90;
                    break;
            }
        },
        closePreviewBox() {
            this.$parent.isShowImgPreview = false;
        },
        arrowFn(arrow) {
             // savePreviewImg   图片预览的列表
            if(arrow === "right") {
                // 向右
                if(this.currentImageIndex === this.$parent.savePreviewImg.length - 1) {
                    this.currentImageIndex = 0;
                } else {
                    this.currentImageIndex++;
                }
            } else if(arrow === "left") {
                // 向左
                if(this.currentImageIndex === 0) {
                    this.currentImageIndex = this.$parent.savePreviewImg.length - 1;
                } else {
                    this.currentImageIndex--;
                }
            }
        }
    },
};
</script>

<style scoped>
.image-preview-box {
    position: fixed;
    background-color: #fff;
    z-index: 999;
    border: 1px solid #EBEBEB;
}
.image-preview-box .tit-box {
    height: 3%;
    width: 100%;
}
.image-preview-box .image-preview-list-box {
    width: 100%;
    height: 75%;
    position: relative;
}
.image-preview-list-box .left-arrow,
.image-preview-list-box .right-arrow  {
    width: 35px;
    height: 35px;
    font-size: 18px;
    color: #fff;
    background-color: #606266;
}
.image-preview-list-box .left-arrow {
    position: absolute;
    left: 10px;
    top: 50%;
}
.image-preview-list-box .right-arrow {
    position: absolute;
    right: 10px;
    top: 50%;
}
.image-preview-list {
    width: 90%;
    height: 100%;
    margin: 15px auto;
}
.image-preview-list li,
.image-preview-list img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    overflow: hidden;
}
.tit-box .center-tit {
    text-align: center;
    color: #595959;
    font-weight: 700;
    margin-top: 40px;
}
.right-close-icon {
    top: 20px;
    right: 20px;
    width: 40px;
    height: 40px;
    font-size: 24px;
    color: #fff;
    background-color: #606266;
}


/* 定义所有操作按钮  */
.image-viewer__btn {
    position: absolute;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    opacity: 0.8;
    cursor: pointer;
    box-sizing: border-box;
    user-select: none;
}
.image-viewer__actions {
    left: 50%;
    bottom: 20px;
    transform: translateX(-50%);
    width: 282px;
    height: 44px;
    padding: 0 23px;
    background-color: #606266;
    border-color: #fff;
    border-radius: 22px;
}
.image-viewer__actions__inner {
    width: 100%;
    height: 100%;
    text-align: justify;
    cursor: default;
    font-size: 23px;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: space-around;
}
.image-viewer__actions__inner .anticon {
    cursor: pointer;
}
</style>

二、父级组件使用

引入注册后:

// 1、currentPreviewId : ""   // 保存当前预览项的id
<ImgPreviewHasName :currentPreviewId="currentPreviewId" v-if="isShowImgPreview"></ImgPreviewHasName>
// 2、
<img @click="showImagePreview(item)" :src="item.coverUrl" alt="">
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原谅我很悲

不要打赏哦,加个好友一起学习呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值