基于vue3 图片上传、预览、删除封装


<template>
	<!-- 上传后显示 -->
	<div id="look">
		<div id="look-img" v-for="(item, index) in imgSrc" :key="index">
			<img :src="item" alt="" />
			<div id="look-operate">
				<img src="https://s1.ax1x.com/2022/08/08/vMEtPO.png" alt="" title="点击查看" @click="toLook(index)" />
				<img src="https://s1.ax1x.com/2022/08/08/vMEaxH.png" alt="" title="点击删除" @click="toDelete(index)" />
			</div>
		</div>
		<!-- 上传图片按钮 -->
		<div id="demo" v-show="uploadNum">
			<input ref="fileBtn" type="file" id="input-file" accept="image/png,image/gif,image/jpeg" multiple @change="toUpload($event)" />
			<img src="https://s1.ax1x.com/2022/08/08/vMEwMd.png" alt="" id="upload-img" />
		</div>
	</div>
	<!-- 图片预览 -->
	<div
		id="preview"
		v-if="show"
		@click="
			() => {P
				show = false;
			}
		">
		<div id="preview-close">
			<img
				src="https://s1.ax1x.com/2022/08/08/vMEURe.png"
				alt=""
				title="关闭"
				@click="
					() => {
						show = false;
					}
				" />
		</div>
		<div id="preview-pre" v-if="picWhere !== 0" @click.stop="previewLast()">
			<img src="https://s1.ax1x.com/2022/08/08/vMEBqI.png" alt="" title="上一张" />
		</div>
		<div id="preview-next" v-if="picWhere !== imgSrc.length - 1" @click.stop="previewNext()">
			<img src="https://s1.ax1x.com/2022/08/08/vMErZt.png" alt="" title="下一张" />
		</div>
		<img :src="picSrc" alt="" />
	</div>

	<!-- 图片上传 -->
	<div>
		<q-btn rounded dense size="md" @click="toSaveImg"> <div class="q-px-md">上传</div></q-btn>
	</div>
</template>
<script >
import { getVueModules} from 'components/util';

export default {
	computed: {
		baseUrl() {
			return this.$axios.defaults.baseURL;
		},
		jwtToken() {
			return this.$axios.defaults.headers.common.Authorization;
		},
	},
	setup(props) {
		const { toRefs, reactive, router, store, proxy, onMounted, ref } = getVueModules(),
			reactiveData = reactive({
				imgSrc: [], //已上传图片数组
				arrLength: 3, //上传图片数量
				uploadNum: true, //控制上传按钮的显示隐藏
				show: false, //控制预览图片遮罩层显示隐藏
				picSrc: '', //预览图片地址
				picWhere: 0, //选择哪一张进行预览以及控制上一张下一张
				imgEndArr: [], // 最终传给后端的图片数组
				fileBtn: null
			}),
			methods = {
				// 单个图片上传回显
				toUpload(e) {
					let file = e.target.files[0];
					// 图片上传回显
					methods.uploadImg(file);

					// 使用base64 回显,此时不掉后端接口,最后保存的时候统一调接口
					// let reader = new FileReader();
					// let file = e.target.files[0];
					// // 图片上传完,转换成base64类型,实现预览
					// reader.readAsDataURL(file);
					// reader.onload = () => {
					// 	reactiveData.imgSrc.push(reader.result);
					// 	methods.toJudgeNum();
					// 	reactiveData.fileBtn.value = '';
					// };
				},

				uploadImg(file) {
					let formData = new FormData();
					formData.append('file', file);
					$.ajax({
						url: `${proxy.baseUrl}/order/upload_image`,
						type: 'POST',
						data: formData,
						headers: {
							Authorization: proxy.jwtToken,
						},
						async: false,
						cache: false,
						contentType: false, //不设置内容类型
						processData: false, //不处理数据
						success: res => {
							// 后端上传返回的路径显示路径
							reactiveData.imgSrc.push(res?.data?.filePath)
							// 最终需要传给后端的传参
							reactiveData.imgEndArr.push(res?.data);
						},
						error: function () {
							notifyError('上传图片失败');
						},
					});
				},

				// 判断照片数量是否满足规定数量;满足则隐藏上传按钮
				toJudgeNum() {
					if (reactiveData.imgSrc.length >= reactiveData.arrLength) {
						reactiveData.uploadNum = false;
					} else {
						reactiveData.uploadNum = true;
					}
				},

				//删除图片
				toDelete(i) {
					reactiveData.imgSrc.splice(i, 1);
					reactiveData.imgEndArr.splice(i, 1)
					methods.toJudgeNum();
				},

				// 图片预览
				toLook(i) {
					console.log(reactiveData.imgSrc);
					reactiveData.picWhere = i;
					reactiveData.show = true;
					reactiveData.picSrc = reactiveData.imgSrc[reactiveData.picWhere];
				},

				//预览上一张
				previewLast() {
					reactiveData.picWhere--;
					reactiveData.picSrc = reactiveData.imgSrc[reactiveData.picWhere];
				},

				// 预览下一张
				previewNext() {
					reactiveData.picWhere++;
					reactiveData.picSrc = reactiveData.imgSrc[reactiveData.picWhere];
				},

			
				// 64转file,如果有的后端传base 64,此处不用转
				// base64ConvertFile(urlData) {
				// 	if (typeof urlData !== 'string') {
				// 		return;
				// 	}
				// 	let arr = urlData.split(',');
				// 	let type = arr[0].match(/:(.*?);/)[1];
				// 	let fileExt = type.split('/')[1];
				// 	let bstr = atob(arr[1]);
				// 	let n = bstr.length;
				// 	let u8arr = new Uint8Array(n);
				// 	let filename = new Date().getTime();
				// 	while (n--) {
				// 		u8arr[n] = bstr.charCodeAt(n);
				// 	}
				// 	return new File([u8arr], `${filename}.` + fileExt, {
				// 		type: type,
				// 	});
				// },

				// 上传,图片统一一并上传,不要单个上传服务器(因为图片会修改)
				// toSaveImg() {
				// 	for (let i = 0; i < reactiveData.imgSrc.length; i++) {
				// 		let formData = new FormData();
				// 		// base64 转 file
				// 		let reader = new FileReader();
				// 		formData.append('file', methods.base64ConvertFile(reactiveData.imgSrc[i]));
				// 		$.ajax({
				// 			url: `${proxy.baseUrl}/order/upload_image`,
				// 			type: 'POST',
				// 			data: formData,
				// 			headers: {
				// 				Authorization: proxy.jwtToken,
				// 			},
				// 			async: false,
				// 			cache: false,
				// 			contentType: false, //不设置内容类型
				// 			processData: false, //不处理数据
				// 			success: res => {
				// 				reactiveData.imgEndArr.push(res?.data);
				// 			},
				// 			error: function () {
				// 				notifyError({}, '上传图片失败');
				// 			},
				// 		});
				// 	}
				// },
			};

		onMounted(async function () {});

		return {
			...toRefs(reactiveData),
			...methods,
		};
	},
};
</script>
 
 
<style scoped>
	#demo {
	width: 100px;
	height: 100px;
	position: relative;
	border: 3px dashed #dcdcdc;
	display: flex;
	justify-content: center;
	align-items: center;
	margin-left: 1em;
	margin-top: 1em;
}

#input-file {
	opacity: 0;
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	cursor: pointer;
}

#upload-img {
	display: block;
	width: 50px;
	height: 50px;
}

#look {
	width: 70vh;
	display: flex;
	flex-wrap: wrap;
	justify-content: left;
	align-items: center;
}

#look-img {
	width: 100px;
	height: 100px;
	margin-left: 1em;
	margin-top: 1em;
	display: flex;
	justify-content: space-around;
}

#look-img img {
	display: block;
	width: 100px;
	height: 100px;
	cursor: pointer;
}

#look-operate {
	background: rgba(0, 0, 0, 0.6);
	width: 100px;
	height: 0px;
	position: absolute;
	transition: 1s;
	display: flex;
	justify-content: center;
	align-items: center;
}

#look-operate img {
	display: block;
	width: 2em;
	height: 0em;
	cursor: pointer;
}

#look-img:hover #look-operate {
	height: 100px;
	/* opacity: 50%; */
}

#look-img:hover #look-operate > img {
	height: 2em;
}

#preview {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.8);
	display: flex;
	justify-content: center;
	align-items: center;
	z-index: 9999;
}

#preview img {
	width: 40%;
}

#preview-close {
	position: absolute;
	top: 40px;
	right: 0;
	display: flex;
	justify-content: center;
}

#preview-pre {
	position: absolute;
	left: 0;
	top: 50%;
	display: flex;
	justify-content: center;
}

#preview-next {
	position: absolute;
	right: 0;
	top: 50%;
	display: flex;
	justify-content: center;
}
</style>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值