背景
公司客戶要求在訂單中添加文件上傳功能,就開始查閱資料之旅了,微信小程序擴展能力中有現成的文件上傳組件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
});
}
},
})
},