移动端Vue2实现文件图片上传功能

57 篇文章 4 订阅

基于 Vue2 + Vant2 组件库实现 :

废话不多说,直接看代码 :

主要代码 :

methods: {
		// 上传图片之前的操作
		beforeRead(file) {
			let arr = file.name.split('.');
			let fileType = '.' + arr[arr.length - 1].toLowerCase();
			const size = file.size / 1024 / 1024 > 100;
			if (this.acceptAllowFiles.includes(fileType)) {
				this.isShowFileList = true;
			} else {
				this.isShowFileList = false;
				this.isMessageTip = true;
				this.tipMessage = `不支持上传${fileType}类型的文件,请重新上传`;
				return;
			}
			if (size) {
				this.isMessageTip = true;
				this.tipMessage = '上传文件不能大于100M';
				this.uploaderList = [];
				return;
			}
			if (this.isShowFileList) {
				this.isMessageTip = false;
			}
			return true;
		},
		async afterRead(params) {
			// 创建FormData对象,上传图片需要转换二进制,这里要用到FormData
			let uploadFormData = new FormData();
			params.status = 'uploading';
			params.message = '上传中...';
			uploadFormData.append('files', params.file);
			axios
				.post('/file/uploadFile', uploadFormData, {
					headers: {
						'Content-Type': 'multipart/form-data',
					},
				})
				.then((res) => {
					let { code } = res || {};
					if (code == '0') {
						params.status = '';
						params.message = '';
						this.getFileList = res.result;
						this.fileName = this.getFileList[0]['fileName'];
						this.formFileData.newFileName =
							this.getFileList[0]['newFileName'];
						// this.quFileItem.fileObj.fileName =
						// 	this.getFileList[0]['fileName'];
						// this.quFileItem.fileObj.newFileName =
						// 	this.getFileList[0]['newFileName'];
						// 增加url值信息
						// this.quFileItem.fileObj.fileUrl =
						// 	this.getFileList[0]['url'];
						// Toast('上传成功');
						this.saveApi();
					} else if (code == '1') {
						if (res.msg) {
							let errMsg = res.msg;
							Toast(errMsg);
						}
						this.uploaderList = [];
					}
				})
				.catch((err) => {
					params.status = 'failed';
					params.message = '上传失败';
					console.log(err, 'err');
				});
		},
		// 保存上传背景接口
		async saveApi() {
			let data = {
				userId: this.formFileData.userId,
				name: this.fileName,
				type: 1, // 类型
				source: 1, // 来源
				newFileName: this.formFileData.newFileName, // 图片上传的新名称
			};
			let res = await uploadBackgroundFileApi(data);
			const { code } = res;
			if (code == '0') {
				Toast('上传成功');
			} else {
				Toast.fail('保存失败');
			}
		},
		// 下载附件
		downLoadFile() {
			if (this.getFileList.length == 0) return;
			window.localStorage.href = this.getFileList[0].url;
		},
		// 删除文件
		handleRemove() {
			this.uploaderList = [];
			this.tipMessage = '';
			this.fileName = '';
		},
	},

全部代码 : 

<!--
  作者:小灰狼
  时间:2023-07
  描述:附件题型
-->
<template>
	<div class="file-row">
		<van-field
			name="uploader"
			:rules="[
				{ required: quFileItem.isRequired, message: '请上传文件' },
			]"
		>
			<template #input>
				<van-uploader
					accept="*"
					v-model="uploaderList"
					:max-count="1"
					:max-size="100 * 1024 * 1024"
					:deletable="is_answered"
					:disabled="!is_answered"
					:before-read="beforeRead"
					:after-read="afterRead"
					@delete="handleRemove"
				>
					<van-button icon="upgrade" plain type="info"
						>上传文件</van-button
					>
				</van-uploader>
				<span
					style="color: #4e96ff"
					v-if="uploaderList.length > 0"
					@click="downLoadFile"
					>{{ fileName }}</span
				>
				<div
					slot="tip"
					class="el-upload__tip"
					style="margin: 20px auto; color: red"
					v-show="isMessageTip"
				>
					{{ tipMessage }}
				</div>
			</template>
		</van-field>
	</div>
</template>

<script>
import axios from 'axios';
import { Toast } from 'vant';
import SessionStore from '@utils/SessionStore';
import { uploadBackgroundFileApi } from '@/api';

export default {
	props: {
		quFileItem: {
			type: Object,
			default: null,
		},
		is_answered: {
			// 控制禁用状态
			type: Boolean,
			default: true,
		},
	},
	data() {
		return {
			fileName: '', // 上传文件名称
			// 上传文件格式
			acceptAllowFiles:
				'.png, .jpg, .jpeg, .gif, .bmp, .flv, .swf,.mkv,.avi,.rm,.rmvb,.mpeg,.mpg,.ogg,.ogv,.mov,.wmv,.mp4,.mp3,.webm,.wav,.mid,.zip,.xls, .xlsx, .doc, .docx, .rar',
			uploaderList: [], // 已上传的文件列表
			getFileList: [], // 存储已上传的文件信息
			isMessageTip: false, // 上传提示语是否展示
			tipMessage: '', // 上传提示语
			isShowFileList: false, // 是否展示文件列表
			formFileData: {
				userId: '', // 用户Id
				name: '默认',
				type: 1, // 类型
				source: 1, // 来源
				newFileName: '', // 图片上传的新名称
			},
		};
	},
	created() {
		this.formFileData.userId = SessionStore.get('userId');
		if (this.quFileItem && this.quFileItem.fileObj.fileName !== '') {
			this.isMessageTip = false;
			this.uploaderList = [
				{
					name: this.quFileItem.fileObj?.fileName,
					url: this.quFileItem.fileObj?.fileUrl,
				},
			];
			this.getFileList = [{ url: this.quFileItem.fileObj?.fileUrl }];
			this.fileName = this.quFileItem.fileObj?.fileName;
		}
	},
	methods: {
		// 上传图片之前的操作
		beforeRead(file) {
			let arr = file.name.split('.');
			let fileType = '.' + arr[arr.length - 1].toLowerCase();
			const size = file.size / 1024 / 1024 > 100;
			if (this.acceptAllowFiles.includes(fileType)) {
				this.isShowFileList = true;
			} else {
				this.isShowFileList = false;
				this.isMessageTip = true;
				this.tipMessage = `不支持上传${fileType}类型的文件,请重新上传`;
				return;
			}
			if (size) {
				this.isMessageTip = true;
				this.tipMessage = '上传文件不能大于100M';
				this.uploaderList = [];
				return;
			}
			if (this.isShowFileList) {
				this.isMessageTip = false;
			}
			return true;
		},
		async afterRead(params) {
			// 创建FormData对象,上传图片需要转换二进制,这里要用到FormData
			let uploadFormData = new FormData();
			params.status = 'uploading';
			params.message = '上传中...';
			uploadFormData.append('files', params.file);
			axios
				.post('/file/uploadFile', uploadFormData, {
					headers: {
						'Content-Type': 'multipart/form-data',
					},
				})
				.then((res) => {
					let { code } = res || {};
					if (code == '0') {
						params.status = '';
						params.message = '';
						this.getFileList = res.result;
						this.fileName = this.getFileList[0]['fileName'];
						this.formFileData.newFileName =
							this.getFileList[0]['newFileName'];
						// this.quFileItem.fileObj.fileName =
						// 	this.getFileList[0]['fileName'];
						// this.quFileItem.fileObj.newFileName =
						// 	this.getFileList[0]['newFileName'];
						// 增加url值信息
						// this.quFileItem.fileObj.fileUrl =
						// 	this.getFileList[0]['url'];
						// Toast('上传成功');
						this.saveApi();
					} else if (code == '1') {
						if (res.msg) {
							let errMsg = res.msg;
							Toast(errMsg);
						}
						this.uploaderList = [];
					}
				})
				.catch((err) => {
					params.status = 'failed';
					params.message = '上传失败';
					console.log(err, 'err');
				});
		},
		// 保存上传背景接口
		async saveApi() {
			let data = {
				userId: this.formFileData.userId,
				name: this.fileName,
				type: 1, // 类型
				source: 1, // 来源
				newFileName: this.formFileData.newFileName, // 图片上传的新名称
			};
			let res = await uploadBackgroundFileApi(data);
			const { code } = res;
			if (code == '0') {
				Toast('上传成功');
			} else {
				Toast.fail('保存失败');
			}
		},
		// 下载附件
		downLoadFile() {
			if (this.getFileList.length == 0) return;
			window.localStorage.href = this.getFileList[0].url;
		},
		// 删除文件
		handleRemove() {
			this.uploaderList = [];
			this.tipMessage = '';
			this.fileName = '';
		},
	},
};
</script>

<style lang="scss" scoped></style>

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
移动端Vue Vant的Uploader组件可以很方便地实现上传、压缩和旋转图片功能。首先,我们需要在Vue项目中引入Vue Vant库,并在需要使用Uploader的组件中注册该组件。 在页面中使用Uploader组件时,我们可以设置相关的属性来实现功能需求。首先是上传图片功能,可以通过设置`action`属性来指定图片上传的后端接口地址。上传成功后,可以通过监听`@success`事件来处理上传成功的逻辑,例如显示上传成功的提示信息或者将上传成功的图片URL保存到数据库等。 对于压缩图片的功能,我们可以使用该组件提供的`beforeRead`方法来获取用户要上传的图片文件对象。然后,利用`HTMLCanvasElement`的`toBlob`方法对图片进行压缩,并将压缩后的图片对象传给Uploader组件进行上传。在压缩图片时,可以设置压缩的尺寸或者压缩的质量、压缩比等参数,以控制压缩后的图片大小适应实际需求。 要实现图片旋转的功能,我们可以利用`EXIF.js`库来读取图片的EXIF信息,获取图片的拍摄方向。然后,根据拍摄方向来确定图片需要旋转的角度,再借助`canvas`的`rotate`方法对图片进行旋转。旋转后的图片可以在`@success`事件触发后重新渲染到页面上,或者直接发送到后端进行保存。 总结来说,移动端Vue Vant的Uploader组件通过设置相关属性和监听事件,配合压缩工具和EXIF库,可以非常方便地实现图片上传、压缩和旋转功能,满足移动端图片处理的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值