vue上传图片(压缩图片、预览、带token上传)

			<!--这里使用的是antdvue上传组件-->
			<a-form-item label="上传账单:" v-bind="validateInfos.attachment">
				<a-upload v-model:file-list="fileList" name="file" :multiple="true" list-type="picture-card"
					:show-upload-list="true" class="avatar-uploader"
					action="提交的服务器地址" :headers="headers"
					@change="handleChange" @preview="handlePreview" :before-upload="beforeAvatarUpload">
					<span v-if="fileList.length == 0 && showErr" class="textErr">请上传账单</span>
					<div v-if="fileList.length == 0 || !fileList.length">
						<loading-outlined v-if="loading"></loading-outlined>
						<plus-outlined v-else></plus-outlined>
						<div class="ant-upload-text">上传照片</div>
					</div>
				</a-upload>
				<div style="color: #c9c9c9;">支持.jpg .png格式</div>
				<!--预览大图模态框-->
				<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
					<img alt="example" style="width: 100%" :src="previewImage" />
				</a-modal>
			</a-form-item>
<script lang="ts">
	import {
		defineComponent,
		ref,
		onMounted,
		toRaw,
		reactive
	} from 'vue';
	import {
		PlusOutlined,
		LoadingOutlined
	} from '@ant-design/icons-vue';
	import {
		message,
		Form
	} from 'ant-design-vue';
	import * as api from '../api.js'
	import {
		useUserStore,
	} from "/@/store/modules/user";
	interface FileItem {
		uid: string;
		name ? : string;
		status ? : string;
		response ? : string;
		url ? : string;
		type ? : string;
		size: number;
		originFileObj: any;
	}
	interface FileInfo {
		file: FileItem;
		fileList: FileItem[];
	}
	// 预览图片
	function getBase64(file: File) {
		return new Promise((resolve, reject) => {
			const reader = new FileReader();
			reader.readAsDataURL(file);
			reader.onload = () => resolve(reader.result);
			reader.onerror = error => reject(error);
		});
	}
	export default defineComponent({
		props: ['visible', 'id'],
		components: {
			LoadingOutlined,
			PlusOutlined,
		},
		setup(props, {
			emit
		}) {
			// 上传账单验证
			let showErr = ref < boolean > (false);
			const userStore = useUserStore();
			const token = userStore.getToken;
			const headers = "Bearer " + token
			const fileList = ref([]);
			const loading = ref < boolean > (false);
			const previewVisible = ref < boolean > (false);
			const previewImage = ref < string | undefined > ('');
			//上传
			const handleChange = (info: FileInfo) => {
				if (!info.file.status) {
					fileList.value = []
					return
				}
				fileList.value = info.fileList.slice(-1)
				if (info.file.status === 'uploading') {
					loading.value = true;
					return;
				}
				if (info.file.status === 'done') {
					loading.value = false;
					formData.attachment = {
						fileName: info.file.name,
						url: info.file.response.data
					}
					console.log(formData.attachment)
				}
				if (info.file.status === 'error') {
					loading.value = false;
					message.error('upload error');
				}
			};
			// 点击预览
			const handlePreview = async (file: FileItem) => {
				if (!file.url && !file.preview) {
					file.preview = (await getBase64(file.originFileObj)) as string;
				}
				previewImage.value = file.preview;
				previewVisible.value = true;
			};
			// 关闭预览
			const handleCancel = () => {
				previewVisible.value = false;
			};
			// 上传前判断
			const beforeAvatarUpload = (file) => {
				//判断是否为image类型  压缩图片
				if (file.type.indexOf("image") == 0) {
					//判断图片大小是否小于1m  小于就不压缩
					const isLt1m = file.size / 1024 / 1024 < 0.98;
					if(isLt1m) return
					return new Promise(resolve => {
						// 压缩图片需要的一些元素和对象
						let reader = new FileReader(),
							img = new Image();
						reader.readAsDataURL(file);
						reader.onload = function(e) {
							img.src = e.target.result;
						};

						img.onload = function() {
							// 缩放图片需要的canvas
							let canvas = document.createElement('canvas');
							let context = canvas.getContext('2d');
							// 图片原始尺寸
							let originWidth = this.width;
							let originHeight = this.height;
							// 最大尺寸限制
							var maxWidth = 1000,
								maxHeight = 1000;
							// 目标尺寸
							var targetWidth = originWidth,
								targetHeight = originHeight;
							// 图片尺寸超过1000x1000的限制
							if (originWidth > maxWidth || originHeight > maxHeight) {
								if (originWidth / originHeight > maxWidth / maxHeight) {
									// 更宽,按照宽度限定尺寸
									targetWidth = maxWidth;
									targetHeight = Math.round(maxWidth * (originHeight /
										originWidth));
								} else {
									targetHeight = maxHeight;
									targetWidth = Math.round(maxHeight * (originWidth /
										originHeight));
								}
							}
							// 目标尺寸,canvas对图片进行缩放
							canvas.width = targetWidth;
							canvas.height = targetHeight;
							// 清除画布
							context.clearRect(0, 0, targetWidth, targetHeight);
							// 图片压缩
							context.drawImage(img, 0, 0, targetWidth, targetHeight);
							// canvas转为blob并上传
							canvas.toBlob(
								blob => {
									let imgFile = new File([blob], file.name, {
										type: file.type
									}); // 将blob对象转化为图片文件
									resolve(imgFile);
								},
								file.type,
								0.2
							); // file压缩的图片类型
						};
					});
				} else {
					message.error("上传图片只能是 .jpg和.png 格式!");
					return false;
				}
				//仅判断图片大小
				// const imgType = file.type === 'image/jpeg' || file.type === 'image/png'
				// const isLt1m = file.size / 1024 / 1024 < 0.98;
				// console.log(file.size, file.size / 1024 / 1024)
				// if (!imgType) {
				// 	message.error("上传图片只能是 JPG和png 格式!");
				// 	return false;
				// }
				// if (!isLt1m) {
				// 	message.error("上传图片大小不能超过 1M!");
				// 	previewImage.value = file.preview;
				// 	console.log(file)
				// 	return false;
				// }
			}
			return {
				headers: {
					authorization: headers,
				},
				fileList,
				loading,
				handleChange,
				handlePreview,
				previewVisible,
				previewImage,
				handleCancel,
				beforeAvatarUpload,
				showErr,
			};
		},
	});
</script>
			
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值