uni-app 微信小程序 上传图片文件,uniapp。uni-file-picker 和数据一起上传图片,上传图片的时候携带数据。多图上传 电脑版发表于:2023/9/17 23:00 [TOC] #### uni-app中上传图片可以使用方法uni.uploadFile uni.uploadFile官方文档: https://uniapp.dcloud.net.cn/api/request/network-file.html 如果是支持图片和视频的上传可以使用`uni.chooseMedia`,官方文档: https://uniapp.dcloud.net.cn/api/media/video.html#choosemedia 这里借助了uni.chooseImage来选择图片,然后使用uni.uploadFile调用了上传图片的接口实现上传,大致的使用方法为 ``` uni.chooseImage({ success: (chooseImageRes) => { const tempFilePaths = chooseImageRes.tempFilePaths; uni.uploadFile({ url: 'https://www.xxyy.com/api/upload', //你后端的上传地址 filePath: tempFilePaths[0], name: 'file',//后端接收图片上传的名称,后端有些接收写法需要保持一致 formData: { 'user': 'aj', 'truckDriverId':66 },//其它上传参数 success: (uploadFileRes) => { console.log(uploadFileRes.data); } }); } }); ``` 在多贴一个使用`uni.uploadFile`上传图片的示例,里边包含传递token的: ``` // 上传签字图片 const uploadFile = (_filePath:any)=>{ uni.uploadFile({ // 请求接口地址 url: ApiBaseUrl + '/oss/api/SmartFiles/UpLoadFormXXX', filePath: _filePath, name: 'file', header: { 'Authorization': `Bearer ${getToken()}`, }, formData: { 'bucketName': 'teacher-certification', 'filePath': 'teacherTraining', 'fileType': '1' }, success: (uploadFileRes:any) => { let result = JSON.parse(uploadFileRes.data) // 下面是图片上传成功之后配合其他接口的操作 // state.UpLoadData.Sign = result.data.id // submitUpload() } }); } ``` 如果是.net 6的后端接收图片可以这样写,后端这样写的话name就要后后端的命名保持一致了。  主要的结构如下: ``` <view class="avatar" @click="HeadUpload">上头像传</view> <script> ... methods:{ HeadUpload(){ uni.chooseImage(){ .... } } } </script> ``` 然后上传成功后还需要自己处理图片的显示什么的,不然不能看到图片上传的效果,还是挺麻烦的。所以,为了方便,我们可以使用uni-file-picker+uni.uploadFile组合。用uni-file-picker来选择图片,它自己就自带了图片的预览和放大以及删除等功能。当然如果是一些比较简单的单图的上传,比如上传头像什么的,其实直接使用uni.chooseImage和uni.uploadFile基本就够用了。 ### 使用uni-file-picker+uni.uploadFile组合上传图片文件等 先引入uni-file-picker控件后,使用一下 ``` <uni-file-picker limit="1" title="请选择图片" @select="upload($event)":auto-upload="false"></uni-file-picker> ``` 这里限制了只能传递一张图片,显示的效果如下,这个组件自带了很多功能还是很方便的。 <img src="https://img.tnblog.net/arcimg/aojiancc2/494195630cbd4e058aa49f586e197cac.png" style="width:399px;height:auto;"> 我们在`@select`图片选择事件里边加入了upload方法,该方法如下: ``` upload(e) { let url = apiUrl + "api/TruckScale/Add"; const tempFilePaths = e.tempFilePaths; //e是获取的图片源 console.log(tempFilePaths[0]) uni.uploadFile({ url: url, //上传图片的后端接口 filePath: tempFilePaths[0], header: { 'Authorization': `Bearer ${login.getValue("token")}`, }, formData: this.valiFormData, //其它上传参数,根据情况自己控制 name: 'file', success: res => { console.log("上传成功了",res) //this.formData.avatar = res.data } }) } ``` 这样我们一选择就可以直接调用uni.uploadFile上传图片了,但是如果我们并不想一选择图片就直接上传了,而是选择了图片还要填写一些数据后,点击提交按钮,才把数据和图片一起提交到后台,我们就可以在选择事件里边把图片信息记录下来,而不是在选择事件里边直接上传了。 ### 使用uni-file-picker+uni.uploadFile实现图片和数据一起上传 实现填写好资料,选择图片之后在点击提交按钮,在把数据和图片一起提交到后台 <img src="https://img.tnblog.net/arcimg/aojiancc2/f58601c50bc14ed1b8c98da5fc23954c.png" style="width:399px;height:auto;"> **先写好uni-file-picker控件** ``` <uni-file-picker limit="1" title="请选择图片" @select="selectFileFun($event)" @delete="pickerDelete($event)" :auto-upload="false"></uni-file-picker> ``` 主要是看`@select`选择图片的事件,我们是把选择的图片存储起来而不是直接提交 ``` //选择图片 selectFileFun(e) { // 把图片存储到集合里边备用 e.tempFilePaths.map(item => { this.imageList.push(item) }) console.log("选择的图片", this.imageList) }, ``` ``` data() { return { imageList: [] // 存放临时选择的图片信息 } }, ``` **然后在提交按钮里边去调用上传图片的方法即可** 这里有配合表单验证,因为我们除了需要传递图片之外还需要传递表单的数据 ``` submit(ref) { let _this = this //console.log("看看图片集合", _this.imageList) //console.log("看看图片地址", _this.imageList[0]) this.$refs[ref].validate().then(res => { console.log('success', res); let url = apiUrl + "api/TruckScale/Add"; uni.uploadFile({ url: url, filePath: _this.imageList[0], formData: this.valiFormData, //其它上传参数 name: 'file', //这里上传的名字也不能乱写哦,和后台保持一致 header: { 'Authorization': `Bearer ${login.getValue("token")}`, }, success: (res) => { console.log("上传成功!!") console.log(res) }, fail: error => { console.log("上传失败!", error) uni.showModal({ title: '提示', content: error, showCancel: false }); uni.hideLoading(); }, complete: () => { uni.hideLoading(); } }); }).catch(err => { console.log('err', err); }) }, ``` 删除图片那个事件处理方法也贴一下把,就是从集合里边删除即可: ``` // 删除图片 pickerDelete(e) { this.imageList.map((item, i) => { if (item == e.tempFilePath) { this.imageList.splice(i, 1) } }) }, ``` ### 多图的上传 当然先把uni-file-picker控件的limit修改为大于1 ``` <uni-file-picker limit="3" title="请选择图片" @select="selectFileFun($event)" @delete="pickerDelete($event)" :auto-upload="false"></uni-file-picker> ``` 看官方文档中关于uploadFile的介绍: https://uniapp.dcloud.net.cn/api/request/network-file.html 可以使用files一次性传递多个图片,但是要注意后面的说明貌似只支持App和H5,微信小程序应该是不支持这样的方式实现多图或者多文件上传的  先介绍一下这种方式的使用,其实和单张上传很类似的,但是要注意多图上传的时候imageList就不能只给一个地址了,还需要给一个名称,也就是我们需要修改一下选择图片事件里边的逻辑,记录的时候多记录一下名称 ``` // 选择图片 selectFileFun(e) { // 选择文件目前只支持 H5 和 微信小程序平台 , // 且 微信小程序平台 使用 wx.chooseMessageFile() e.tempFilePaths.map(item => { this.imageList.push({ name: 'imageList', uri: item }) }) console.log("选择的图片", this.imageList) }, ``` **可以看到这里我们记录了name和地址uri,但是上传的时候就直接把这个imageList传递回去即可:** ``` submit(ref) { let _this = this this.$refs[ref].validate().then(res => { console.log('success', res); let url = apiUrl + "api/TruckScale/BatchAdd"; uni.uploadFile({ url: url, files: _this.imageList,//多图上传使用files // filePath: _this.imageList[0], name: 'files', //这里上传的名字也不能乱写哦,和后台保持一致 formData: this.valiFormData, //其它上传参数 header: { 'Authorization': `Bearer ${login.getValue("token")}`, }, success: (res) => { console.log("上传成功!") console.log(res) }, fail: error => { console.log("上传失败!", error) uni.showModal({ title: '提示', content: error, showCancel: false }); uni.hideLoading(); }, complete: () => { uni.hideLoading(); } }); }).catch(err => { console.log('err', err); }) }, ``` **.net6后台也简单贴一下:** ``` // 多图上传 [HttpPost] [ApiDescriptionSettings(Name = "BatchAdd")] public async Task BatchAdd([FromForm] AddTruckScaleInput input) { var request = App.HttpContext.Request; IFormFileCollection cols = request.Form.Files; List<IFormFile> formFiles = new List<IFormFile>(); foreach (IFormFile file in cols) { formFiles.Add(file); } // 调用封装的多图上传方法,这个根据自己的情况修改即可 var fileRes = await _fileService.UploadFiles(formFiles, "Upload/Scale"); } ``` 使用request.Form.Files即可获取前台传递的多图,调用自己的方法存储即可。 **删除图片那个事件处理方法也贴一下把,就是从集合里边删除即可:** 这里和单独删除哪里有一点点区别就是不能直接去判断了,需要使用item.uri才是图片地址 ``` // 删除图片 pickerDelete(e) { this.imageList.map((item, i) => { if (item.uri == e.tempFilePath) { this.imageList.splice(i, 1) } }) }, ``` 当然至于微信小程序不支持多图上传可以考虑其他方式,比如官方介绍的可以使用循环调用单图上传的方式。