vue项目中编写一个图片预览的公用组件

今天产品提出了一个查看影像的功能需求。
在查看单据的列表中,有一列是影像字段,一开始根据单据号调用接口查看是否有图片附件,如果有则弹出一个全屏的弹出层,如果没有给出提示。而且,从列表进入详情之后,附件那边也会有一个查看影像的按钮。
所以,根据需求,多个组件需要用到查看影像的功能,所以考虑做一个公用组件,通过组件传值的方法将查看影像文件的入参传过去。
后来,产品要求图片可以旋转缩放。

废话不多说,贴上代码:

<template>
	<div class="filePreview">
		<el-dialog 
		class="imgList" 
		title="预览图片列表" 
		:visible.sync="imgListShow"
		@close="$emit('remove')" 
		fullscreen>
			<div class="allImg">
				<div style="200px;height:100%;margin-top:50px;overflow-y: auto;margin: 0 auto;">
					<img v-for="(item,index) in imgList" :key="item.fileid" :src='item.furl' :class="{ changeColor:changeColor == index}" @click="handlerImg(item,index)">
				</div>
			</div>
			<div style="70%;float:left">
			<el-pagination
				style="margin-bottom:20px;"
				background
				@size-change="handleSizeChange"
				@current-change="handleCurrentChange1"
				:current-page.sync="currentImg"
				:page-size="1"
				layout="prev, pager, next, jumper"
				:total="num">
			</el-pagination>
			<div style="50%;text-align:center;margin:20px 0">
				<button  @click="rotateL" icon="el-icon-arrow-left">
					<i class="el-icon-arrow-left"></i>左旋转
				</button>
				<button  @click="rotateR">右旋转
					<i class="el-icon-arrow-right"></i>
				</button>

				<button  @click="scale">
					<i class="el-icon-zoom-out"></i>缩小
				</button>
				<button  @click="scale1">放大
					<i class="el-icon-zoom-in"></i>
				</button>
				
			</div>
			<div id="test_3" @mousemove="move" @mouseup="stop">
				<p  @mousedown="start" >
					<img :src="furl" ref="singleImg" class="originStyle">
				</p>
			</div>
			</div>
		</el-dialog>
	</div>
</template>

<script>
	import {isgetFilePath}from 'api/public_api.js'

	export default {
		data() {
			return {
				imgList:[],
				imgListShow:false,
				num:0,
				furl:'',
				currentImg:1,
				changeColor:-1,
				currentRotate: 0 ,
				currentScale:1,
				canDrag: false,
				offset_x:0,
				offset_y:0,
				mouse_x:0,
				mouse_y:0,
			}
		},
		props:['filePreviewShow','FDJH'],
		created() {
			this.imgListShow = this.filePreviewShow
			this.preview()
		},
		methods: {
			//点击图片显示
			handlerImg(obj,index){
				this.currentRotate = 0
				this.currentScale = 1
				this.rotateScale()
				this.$refs.singleImg.style.left = 0
				this.$refs.singleImg.style.top = 0
				this.furl = obj.furl
				this.changeColor = index
				this.currentImg = index+1
			},
			//影像
			preview(){
				let data = {
					// FDJH:'000002'
					FDJH:this.FDJH
				}
				isgetFilePath(data).then(res=>{
					// console.log(res)
					if(res.TYPE == "S"){
						this.imgList = JSON.parse(res.MESSAGE)
						this.num = this.imgList.length
						if(this.imgList.length > 0){
							this.furl = this.imgList[0].furl
							this.changeColor = 0
						}else{
							this.$message.warning('影像文件为空')
						} 
					}else{
						this.$message.warning(res.MESSAGE)
					}
					
					
				})
			},
			handleSizeChange(val) {
				console.log(`每页 ${val} 条`);
			},
			handleCurrentChange1(val) {
				this.currentRotate = 0
				this.currentScale = 1
				this.rotateScale()
				this.$refs.singleImg.style.left = 0
				this.$refs.singleImg.style.top = 0
				this.furl = this.imgList[val-1].furl
				this.changeColor = val-1
			},
			start(e){
				//鼠标左键点击
				e.preventDefault && e.preventDefault(); //去掉图片拖动响应
                if(e.button==0){
					this.canDrag=true;
					//获取需要拖动节点的坐标
					this.offset_x = document.getElementsByClassName('originStyle')[0].offsetLeft;//x坐标
					this.offset_y = document.getElementsByClassName('originStyle')[0].offsetTop;//y坐标
					//获取当前鼠标的坐标
					this.mouse_x = e.pageX;
					this.mouse_y = e.pageY;
                }
			},
			move(e){
				e.preventDefault && e.preventDefault()
                if(this.canDrag==true){
					let _x = e.pageX - this.mouse_x;
                    let _y = e.pageY - this.mouse_y;
                    //设置移动后的元素坐标
                    let now_x = (this.offset_x + _x ) + "px";
                    let now_y = (this.offset_y + _y ) + "px";
					
					document.getElementsByClassName('originStyle')[0].style.top = now_y
					document.getElementsByClassName('originStyle')[0].style.left = now_x
				}
            },
            stop(e){
                this.canDrag = false;
            },
            
			//旋转放大
			rotateScale(){
				this.$refs.singleImg.style.OTransform = 'rotate('+this.currentRotate+'deg)'+'scale('+this.currentScale+')'
                this.$refs.singleImg.style.webkitTransform = 'rotate('+this.currentRotate+'deg)'+'scale('+this.currentScale+')'
                this.$refs.singleImg.style.MozTransform = 'rotate('+this.currentRotate+'deg)'+'scale('+this.currentScale+')'
                this.$refs.singleImg.style.msTransform = 'rotate('+this.currentRotate+'deg)'+'scale('+this.currentScale+')'
                this.$refs.singleImg.style.transform = 'rotate('+this.currentRotate+'deg)'+'scale('+this.currentScale+')'
			},
			//旋转
			rotateL(){
				this.currentRotate += 15
				this.rotateScale()
			},
			rotateR(){
				this.currentRotate -= 15
				this.rotateScale()
			},
			//缩放
			scale(){
				this.currentScale -= 0.1
				if(this.currentScale <= 0.1){
					this.currentScale = 0.1
					this.rotateScale()
				}else{
					this.rotateScale()
				}
			},
			scale1(){
				this.currentScale += 0.1
				this.rotateScale()
			},
		}
	}
</script>

<style rel="stylesheet/scss" lang="scss" slot-scope="scope">
	.filePreview{
		.imgList{
			.el-dialog__headerbtn{
				font-size:26px;
			}
			.el-dialog__body{
				.allImg{
					30%;
					float:left;
					height:600px;
					img{
						 150px;
						height: 150px;
						margin: 5px;
						cursor: pointer;
					}
					.changeColor{
						border:4px solid #409eff;
					}
				}
			}
		}
		.originStyle{
			position:absolute;
			left:0;top:0;
			cursor: pointer;
			// transform-origin: 50% 50%;
		}
		#test_3{
			position: relative;
			 600px;
			height: 400px;
			overflow: hidden;
			// overflow: scroll;
			& > p{
				position: absolute;
				cursor: move;
				transform-origin: center;
				 100%;
				height: 100%;
				padding: 0;
				-webkit-margin-before: 0;
				-webkit-margin-after: 0;
				left: 0;
				top: 0;
				& > img{
					display: inline-block;
					vertical-align: middle;
				}
			}
		}
	}
	
	
</style>

后来出现一个问题,有一类的单据的图片存储在数据库中,之前的图片都是存储在服务器中,只需要传入单据号查询返回给我图片路径即可。

而存储在数据库当中不一样,需要拼接路径,一下是解决方法:

preview(){

		if(this.imgList.length > 0){
			this.imgList.map(item=>{
				item.furl = process.env.APP_EXCEL_PATH+'portal/gys/querydownloadPurchaFile?fileid='+ item.FILEID +'&gysdh='+item.CREATENAME //接口加入参
			})
		}
		this.num = this.imgList.length
		this.furl = this.imgList[0].furl
		this.changeColor = 0
},

一般情况下,图片的预览,图片存储在服务器中,数据库中一般只存储路径。
我们后端我也是醉了,尽给我找事情,说起来都是泪。

原文地址:https://www.cnblogs.com/yinxingen/p/9856473.html