移动端上传文件封装

文章描述了一个移动端上传文件的Vue组件,包括文件选择、大小限制、上传过程中的进度显示以及文件删除功能。使用了FormData和XMLHttpRequest进行文件上传,同时展示了如何处理上传状态和错误情况。
摘要由CSDN通过智能技术生成

在这里插入图片描述

移动端上传文件封装

<template>
	<view class="">
		<view class="uploadbox" @click="upload">
			<view class="addfont">
				+
			</view>
		</view>
		<view ref="input" class="" style="opacity: 0;height: 0;">

		</view>
		<view class="fileList">
			<view class="fileitem" v-for="(item,index) in fileList" :key="index">
				<view class="fonts">{{item.originalFileName}}</view>
				<u-button shape="square" size="mini" class="btns" @click="delBtn(index)">删除</u-button>
			</view>
		</view>
		<!-- 进度条 -->
		<view class="linebox" v-if="ispercentage">
			<u-line-progress active-color="#2979ff" :percentage="percentage" :striped-active="true"></u-line-progress>
		</view>
	</view>
</template>

<script>
	import {
		removFile,
	} from "../service/index.js"
	export default {
		props: {
			type: {
				type: String,
				default: ''
			}
		},
		data() {
			return {
				percentage: 0,
				ispercentage: false,
				fileList: [],
				videoList: ['']
			}
		},
		methods: {
			getSuffix(fileName) { // suffix后缀名,fileName文件名
				var suffix = "";
				var i = fileName.lastIndexOf("."); // 如果不是-1表示该字符串中存在.
				if (i != -1) {
					suffix = fileName.substring(i + 1); // 截取到了后缀名
				}
				return suffix;
			},
			upload() {
				if (this.type == '') {
					uni.showToast({
						icon: 'none',
						title: '请选择类型'
					})
					return false
				}
				var input = document.createElement('input');
				input.type = 'file';
				if (this.type == '1') {
					input.accept = '*'
				} else if (this.type == '2') {
					input.accept = 'video/*'
				}
				this.$refs.input.$el.appendChild(input);
				input.onchange = () => {
					const file = input.files[0];

					if (file.size > (1024 * 1024 * 200)) {
						uni.showToast({
							title: '单个文件请勿超过200M,请重新上传',
							icon: 'none'
						})
					}
					let formData = new FormData();
					formData.append('file', file);
					let xhr = new XMLHttpRequest();
					xhr.open("POST", '请求地址', true);
					xhr.setRequestHeader('Token', uni.getStorageSync("token"));
					xhr.upload.addEventListener("progress", function(event) {
						let percents = Math.ceil(event.loaded * 100 / event.total) + "%";
						if (event.lengthComputable) {
							let percent = Math.ceil(event.loaded * 100 / event.total) + "%";
							uni.showLoading({
								title: `努力上传中..${percent}`
							})
							this.percentage = percent
						}
					}, false);
					xhr.ontimeout = function() {
						// xhr请求超时事件处理
						uni.showToast({
							title: '请求超时'
						})
					};
					this.ispercentage = true
					this.percentage = 0
					xhr.onreadystatechange = () => {
						if (xhr.readyState == 4) {
							console.log('status:' + xhr.status);

							if (xhr.status == 200) {
								uni.hideLoading();
								uni.showToast({
									title: '上传成功',
									icon: 'none'
								})
								const response = JSON.parse(xhr.responseText);
								console.log(response)
								this.fileList.push(response.fileAttribute)
								this.$emit('uploadchange', this.fileList)
								this.percentage = 100
								setTimeout(() => {
									this.hideper()
								}, 1000);
							} else {
								this.hideper()
								uni.hideLoading();
								uni.showToast({
									title: '上传失败',
									icon: 'none'
								})
							}

						}
					};
					xhr.send(formData);



				}
				input.click()
			},
			hideper() {
				this.ispercentage = false
			},
			delBtn(index) {
				uni.showLoading({
					title: `删除中...`
				})
				removFile(this.fileList[index].name).then((res) => {
					if (res && res.success) {
						this.fileList.splice(index, 1);
						this.$emit('uploadchange', this.fileList)
						uni.hideLoading();
						uni.showToast({
							title: '删除成功',
							icon: 'none'
						})
					}
				}).catch((err) => {
					console.log("错误信息:", err);

					uni.hideLoading();
					uni.showToast({
						title: '删除失败',
						icon: 'none'
					})
				})

			}

		}
	}
</script>

<style lang="scss" scoped>
	.uploadbox {
		width: 160rpx;
		height: 160rpx;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		background-color: #f4f5f7;
		border-radius: 2px;
		margin: 0 8px 8px 0;
		box-sizing: border-box;

	}

	.addfont {
		font-size: 60rpx;
	}

	.fileList {
		.fileitem {
			display: flex;
			justify-content: space-between;
			align-items: center;
			border: 1px solid #eee;
			box-sizing: border-box;
			border-radius: 5px;
			margin-bottom: 10px;
			padding: 10px 5px;
			width: 100%;

			.fonts {
				width: 40vw;
				text-overflow: -o-ellipsis-lastline;
				overflow: hidden;
				text-overflow: ellipsis;
				display: -webkit-box;
				-webkit-line-clamp: 3;
				line-clamp: 3;
				-webkit-box-orient: vertical;
				word-break: break-all;
				color: #1275d7;
			}

			.btns {
				width: 80px;
				height: 30px;
				border-radius: 15px;
				color: white;
				background-color: #1275d7a1;

			}
		}
	}

	.linebox {
		width: 100%;
	}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值