当前位置:   article > 正文

uniapp学习笔记——基于<uni-file-picker>组件和uni.uploadFile()方法实现图片上传

uni.uploadfile

1、使用场景

  在编辑页面,有图片字段需要选择手机图片进行上传、预览、回显、删除等,尤其是当提交表单后,再次选择编辑该表单页面时,如何正确的显示图片,并保证再次提交时,可以没有异常。这里主要记录了一种在编辑表单时(图片字段返回的是图片地址)的一种处理方式,不一定是最佳实践,但是可以实现功能的正常使用。

2、组件用法简介

  <uni-file-picker>组件和uni.uploadFile()方法在官方文档已经有非常详细的介绍了,这里只是简单说明一下,需要了解详细信息的请移步官方文档进行查看。

文件上传组件<uni-file-picker>的用法

  文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间。

<uni-file-picker 
	v-model="imageValue" 
	fileMediatype="image" 
	mode="grid" 
	@select="select" 
	@progress="progress" 
	@success="success" 
	@fail="fail" 
/>
<script>
	export default {
		data() {
			return {
				imageValue:[]
			}
		},
		methods:{
			// 获取上传状态
			select(e){
				console.log('选择文件:',e)
			},
			// 获取上传进度
			progress(e){
				console.log('上传进度:',e)
			},
			
			// 上传成功
			success(e){
				console.log('上传成功')
			},
			
			// 上传失败
			fail(e){
				console.log('上传失败:',e)
			}
		}
	}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
文件上传方法uni.uploadFile(OBJECT)

  将本地资源上传到开发者服务器,客户端发起一个 POST 请求,其中 content-type 为 multipart/form-data。

uni.uploadFile({
	url: 'https://www.example.com/upload', //附件上传的服务器接口地址,非真实的接口地址
	filePath: tempFilePaths[0],//要上传文件资源的路径,不同的组件
	name: 'file',//文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容,即附件信息的接收字段名称
	formData: {//HTTP 请求中其他额外的 form data	
		'user': 'test'
	},
	success: (uploadFileRes) => {//回调方法
		console.log(uploadFileRes.data);
	}
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

官方文档地址: 《<uni-file-picker>文件上传组件用法》《uni.uploadFile(OBJECT)方法使用方法》

3、项目实践

  为了满足在前面提到的需求,我定义了一个变量isUploadImage,用于判断在编辑表单时,是否更新了图片。同时为了区分有时候需要上传附件,有时候不需要上传附件,把业务数据提交的方法抽离出了一个doSubmitData()方法。
  首先,当新增时,isUploadImage默认为true,即需要上传附件,这个时候添加附件后,调用doSubmit()时,实际上附件对象file变量为空,通过代码“this.$refs[‘files’].files[0];”获取上传的附件对象(这里其实可以通过监听组件的select或success实现赋值),然后再用uni.uploadFile()方法实现上传时,传入相关对象即可,当上传成功后,会返回图片的上传信息(不同附件上传接口不太一样,我这里返回了图片的名称,而且固定的前缀+图片名称,就可以实现图片的访问),然后把图片的名称再放到业务参数中和业务数据完成数据的提交。
  当编辑时,因为调用了查询详情,这个时候isUploadImage被设置为false,如果没有对图片做任何处理,数据提交时,将不会在提交图片,避免报错(这里应该有更加合理的实践,但是目前没有找到,而且如果没有修改避免再提交占用带宽也挺不错的注意),如果修改就需要删除图片,这个时候就会调用删除方法把isUploadImage设置为true,再次提交数据的时候,又会和新增的时候一样正常提交数据了。
  编辑时的回显,是:value=“imgPath”,并在加载详情的时候,为imgPath赋值实现的,这里的imgPath是一个对象,我为其中url属性赋值了,但是官方文档提示需要三个必填属性(不确定回显后,如果不删除直接上传会保存的问题是不是和这个有关系,未经验证):

  1. “name”:“file.txt”,
  2. “extname”:“txt”,
  3. “url”:“https://xxxx”,
<template>
	<view class="container">
		<uni-forms ref="formData" :modelValue="formData">
			<view class="context-section">
				<u-form-item label="图片附件" label-width="180">
					<uni-file-picker @delete="deleteImage" ref="files" :value="imgPath" file-mediatype="image" mode="grid" :limit="1"/>
					<view style="color: #c0c4cc">请上传图片,图片大小不超过20M</view>
				</u-form-item>
				<view class="mt-3">
					<view style="text-align: center;" >
						<u-button class="btn" type="primary" size="medium" @click="doSubmit" >提交</u-button>
					</view>
				</view>
			</view>
		</uni-forms>
	</view>
</template>

<script>
	import config from '@/config/config';
	export default {
		data() {
			return {
				file: null,
				imgPath: {},
				isUploadImage:true,//处理修改订单时,图片不修改的情况
				formData: {//业务数据,包括附件名称
					id: '',
					fileName: "",
					remark: ""
				}
			}
		},
		onLoad(option) {
			if (option && option.id) { //编辑页面,填充需要修改的数据
				this.getDetail(option.id);
				this.isUploadImage = false;
			}
		},
		
		methods: {
			getDetail(id) {
				this.$u.api.getDetail({
					id: id
				}).then(res => {
					if (res.success == 'true' || res.success) {
						this.formData = res.data
						if (this.formData && this.formData.fileName) {
							console.log(config.filePrefix + this.formData.fileName);
							this.imgPath = {
								'url': config.filePrefix + this.formData.fileName
							}
						}
					}
				});
			},
			deleteImage(e){
				console.log(e);
				this.imgPath = {};
				this.file = null;
				this.isUploadImage = true;//修改了图片允许图片上传
			},
			doSubmit() {
				this.$refs['formData'].validate().then(res => {
					uni.showLoading({
						title: '提交中...'
					});
					if(!this.isUploadImage){//不需要上传图片时
						this.doSubmitData();
						return;
					}
					if (!this.file) {
						if(this.$refs['files'].files.length > 0){
							this.file = this.$refs['files'].files[0];
						}
					}
					if(!this.file){
						console.log("没有附件信息!");
					}
					// 发送文件到后台
					uni.uploadFile({
						url: config.uploadUrl, // 后台接收文件的 API 地址
						filePath: this.file.path,
						name: 'file',
						header: {
							"Content-Type": "multipart/form-data",
						},
						success: (res) => {
							// 文件上传成功后的处理
							console.log(res.data);
							if(res.data){
								let reJson = JSON.parse(res.data);
								if(reJson && reJson.data && reJson.data.length>0){
									this.formData.fileName= reJson.data[0].fileName;
								}
							}
							this.doSubmitData();
						},
						fail: (err) => {
							uni.hideLoading()
							uni.showToast({
								title: '上传附件失败,请稍候再试!',
								duration: 1000,
								icon: 'none'
							});
							return;
						},
					});
				}).catch(err => {
					console.log(err);
					uni.showToast({
						title: "系统异常,错误信息:" + err,
						duration: 1000
					})
				})
			},
			doSubmitData(){//上传业务数据,包括图片地址
				console.log(this.formData);
				this.$u.api.doAdd(this.formData).then(res => {
					uni.hideLoading()
					if (res.success == 'true' || res.success) {
						uni.showToast({
							title: '创建成功!',
							duration: 1000,
							success: function() {
								uni.reLaunch({
									url: '/pages/index/index'
								})
							}
						})
					}
				});
			}
		}
	}
</script>

<style lang="scss">

</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/183475
推荐阅读
相关标签
  

闽ICP备14008679号