背景
公司客户要求在订单中添加文件上传功能,就开始查阅资料之旅了,微信小程序扩展能力中有现成的文件上传组件uploader可以使用,而这个项目是在表单中添加上传图片功能,因此需要考虑一些代码逻辑。
-
首先,刚开始忽略了逻辑问题,直接在上传文件的时候通过接口提交到后台,接着遭到了质疑:“如果用户没提交表单,上传的图片就已经到后台了,有点不合逻辑吧”
-
然后,重新整理逻辑,先把图片临时缓存一下,提交表单的时候,拿到缓存数据,通过接口把图片提交到后台,再把表单数据提交到后台(两个接口是分开的,后台给的,就这样用呗)
uploader简介
uploader是微信小程序WeUI组件库中的一个图片上传的组件,可以在小程序开发文档中--扩展能力--表单组件中找到相关用法。
这是一个集合了图片选择、上传、预览、删除的完整组件,属性定义也比较全面,可以自定义上传个数,有上传成功提醒和失败提醒,点击预览功能等,基本可以涵盖图片文件上传的所有功能要求。
用起来也很方便,在json文件中加入以下引用(可在官方文档找到),然后在wxml文件中直接引入该组件就行,使用起来很方便
{
"usingComponents": {
"mp-uploader": "weui-miniprogram/uploader/uploader"
}
}
官方文档提供了简单的使用案例,如图所示
附上官方地址:
https://developers.weixin.qq.com/miniprogram/dev/extended/weui/uploader.html
官方提供的这部分代码里面其实只需要补充uplaodFile上传方法调用后台上传图片的接口,上传功能就可以使用了,这算是一个可用的完整demo。实际使用起来,还是需要完善一下,废话不多说,直接上代码~
用法与代码
1.在json文件中引入组件
"usingComponents": {
"mp-uploader": "../../weui/uploader/uploader",
}
2.在wxml文件中引入
暂时只需要上传一张图片,设置max-count等于1即可
文字版:
<view class="upload bg1 w90 box-shadow1 mar-ao p10 mar-tp10">
<view class="message w100 p10 bor-bottom " style="color:#444">上传附件</view>
<view class="page__bd" style="padding:0 10px;">
<mp-uploader binddelete="deleteFile" bindfail="uploadError" bindsuccess="uploadSuccess" select="{{selectFile}}"
upload="{{uplaodFile}}" files="{{files}}" max-count="1" title=""></mp-uploader>
<!-- max-size="{{5*1024}}" -->
</view>
3.在js文件中写对应方法
添加官方demo的内容,并修改对应方法,直接贴图:
修改uplaodFile方法,调用resolve({urls})方法设置上传成功状态,保存临时文件目录tempFilePaths,后面提交后台时再来拿数据
上传文件的实现,后面表单提交时调用
表单提交部分,先将上传的图片提交到后台,再把表单数据提交
文字版:
//------------------附件上传开始------------------------
chooseImage: function (e) {
var that = this;
wx.chooseImage({
count: 9,
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
tempFilePaths = res.tempFilePaths;
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
that.setData({
files: that.data.files.concat(res.tempFilePaths)
});
}
})
},
previewImage: function (e) {
wx.previewImage({
current: e.currentTarget.id, // 当前显示图片的http链接
urls: this.data.files // 需要预览的图片http链接列表
})
},
selectFile(files) {
uploadArr = [];
uploadIndex = 0;
for(var i=0;i<files.tempFilePaths.length;i++){
uploadArr.push(files.tempFilePaths[i])
}
console.log(uploadArr,'9999999')
// uploadArr = files.tempFilePaths
// 返回false可以阻止某次文件上传
},
// 缓存文件
uplaodFile(files) {
console.log('upload files', files);
var that = this;
// 文件上传的函数,返回一个promise
return new Promise((resolve, reject) => {
const tempFilePaths = files.tempFilePaths;
that.setData(
{
filesUrl: tempFilePaths
}
)
var object = {};
object['urls'] = tempFilePaths;
resolve(object);
})
},
//上传单个文件
uploadFile(url, filePath) {
return new Promise((resolve, reject) => {
wx.uploadFile({
url: url, //仅为示例,非真实的接口地址
filePath:filePath,
name: 'file',
// formData: param,
success (res){ //上传成功
console.log(res)
//成功调用接口
resolve(JSON.parse(res.data));
},
fail(err){
console.log(err)
wx.showToast({ title: '请求失败,请刷新后重试', icon: 'none' });
reject(err)
}
})
})
},
uploadError(e) {
console.log('upload error', e.detail)
},
uploadSuccess(e) {
console.log('upload success', e.detail)
},
formSubmit:function() {
let uploadUrl = '你的后台接口'
let filePath = uploadArr[uploadIndex]
this.uploadFile(uploadUrl,filePath).then((res) => { //上图图片并保存表单
if (res.Code == "Success") {
wx.showToast({
title: '添加成功'
});
wx.navigateBack({ //返回上一页
delta: 1,
})
}
})
wx:wx.request({
url: '你的后台接口',
method: "POST",
data: that.data.form,
header: {
'Content-Type': 'application/json'
},
success: (res) => {
console.log(res);
if (res.data.code == '200') {
wx.setStorageSync('detailsList', []);
that.setData({pinLeiListData:[]});
Toast({
type: 'success',
message: '提交成功',
onClose: () => {
wx.reLaunch({
url: "/pages/index/index",
})
},
});
}else if(res.data.code == '400'){
Toast({
type: 'fail',
message: res.data.message,
duration:4000
});
}
},
})
},