uni-app上传文件(h5)

需求为:h5页面中,能够上传文件,不仅仅是图片。整体框架用的是uni-app,导致限制很多,尝试了很多方法,最后终于实现了。动态创建input标签,使用xhr上传,代码如下:

1,需要上传的todo.vue页面中,

<view class="flex flex-align-center flex-pack-justify" >
    // 动态创建input标签
	<view class="addBox" ref="input">
		<view class="uploadtitle">点击上传文件</view>
	</view>

    // 上传的文件列表展示
	<view class="filesBox" v-if="fileList.length > 0">
		<view class="fileslist" v-for="item in fileList">
			<image src="/static/images/upfile.png" class="upfileico"></image>
				<text class="upname">{{item.fileOriginalName}}</text>
				<image src="/static/images/upclose.png" class="upclose" @click="delUpFile(item)"></image>
		</view>
	</view>
</view>

2,css样式

.addBox{
		width: 100%;
		height: 100px;
		text-align: center;
        background: url(/static/images/upload.png) no-repeat center center;		
		position: relative;
		border: 1px dashed #1890FF;
		margin: 0 auto;
		border-radius: 8px;
		background-color: #FAFAFA;
	}
	
	.uploadtitle{
		position: absolute;
		bottom: 12rpx;
		left: 0;
		right: 0;
	}
	
	.filesBox{
		margin-top: 28rpx;
	}
	
	.fileslist{
		margin-top: 8px;
	}
	
	.upfileico{
		width: 52rpx;
		height: 52rpx;
		display: inline-block;
		vertical-align: top;
	}
	
	.upname{
		font-size: 26rpx;
		color: #333333;
		width: 80%;
		display: inline-block;
	}
	
	.upclose{
		width: 40rpx;
		height: 40rpx;
		display: inline-block;
		float: right;
		position: relative;
		top: 3px;
	}

3,在mounted中,开始创建input标签,methods里上传后台方法

mounted() {
			this.$nextTick(function(){
				var input = document.createElement('input')
				input.style.width="100%";
				input.type = 'file'//添加file类型
				input.multiple = 'multiple'// 可以选择多个
				// input.accept=".pdf" // 限制只能上传PDF文件,可以不限制,能上传任何类型
				input.style.height="100%";
				input.style.position="absolute";
				input.style.top="0";
				input.style.right="0";
				input.style.opacity="0";
				input.style.overflow="hidden"; //防止注意input 元素溢出
				input.id = 'file';
				var _this = this;
				setTimeout(() => {
					this.$refs.input.$el.appendChild(input); // 这里可能会报$el找不到错误,所以加了延时器,报错的原因是this.$refs.input没有找到为null,所以需要等页面结构加载完后再将其添加进去
					input.onchange = (event) => { // 点击上传选择文件
						var file = event.target.files;
						if (file.length > 0) {
							file.forEach(item => { // 因为后台限制,只能一个一个文件的上传,所以当选择多个文件后,需要遍历一个一个调用上传接口
								_this.uploadAPI(item); // 上传图片
							})
						}
					}
				}, 1000)
			})
			
		},

methods: {
   uploadAPI(path){
			  uni.showLoading({
				 title: '上传中'
			  })
			  var _this=this
			  var fData = new FormData();
			  fData.append("file",path);
			  fData.append("moduleName",'reports');
			  var xhr = new XMLHttpRequest();
			  var surl = util.commonUrl() + api.uploadUrl;
			  xhr.open("POST",surl,true); 
			  xhr.onload = function(e) {
				  // console.log("上传成功",e); //上传成功
			  };
			  xhr.onreadystatechange = () =>{
				  if(xhr.readyState == 4 && xhr.status == 200){    //上传后台成功
				      uni.hideLoading()
					  var res =JSON.parse(xhr.responseText)
					  _this.fileList.push(res.datas); // 上传成功后放进fileList数组用于展示
				
				  } else {
					  uni.hideLoading()
				  }
			  }
              
              // 这里设置请求头,做的时候遇到一个问题,明明上传的是FormData,可是在请求中变成了request payload,后台需要的是FormData,解决方法,设置enctype为multipart/form-data,不要设置Content-Type,切记直接不设置Content-Type
			  xhr.setRequestHeader('enctype',"multipart/form-data");
			  xhr.setRequestHeader('Authorization',util.getToken());
			  xhr.send(fData)
		  },
		  
		  /**
		  * 列表删除文件
		  * 
		  */
		  delUpFile(data){
			  this.fileList = this.fileList.filter(item => item.id !== data.id)
		  }


}

4,结果图

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页