最近剛開發了小程序上傳圖片功能,為了便於后續查找,特此記錄歸總。
在實際開發過程中,圖片上傳功能是很常用的功能,所以將其封裝成組件,避免后續重復勞動力,已是不爭的事實。
一、先將圖片上傳功能能封裝成公用模塊(common.js)中,便於其它其它功能調用。此處封裝了單張圖片上傳和多張圖片上傳。
common.js 文件

/** * 文件上傳 */ function uploader(file, callback) { wx.uploadFile({ url: "http://10.109.86.1:5300/education/api/education/ImageUploader", //服務端Url filePath: file, //需要上傳的文件 name: 'anqindayviews', //文件名稱 header: { "Content-Type": "multipart/form-data" }, success: function(res) { if (res && res.data) { var data = JSON.parse(res.data); if (data.isSuccess && callback) { callback(data.content); } else { wx.hideToast(); wx.showModal({ title: '錯誤提示', content: '上傳圖片失敗', showCancel: false }); } } } }); }; /** * 采用遞歸的方式多文件上傳 * imgPaths:需要上傳的文件列表 * index:imgPaths開始上傳的序號 * successFiles:已上傳成功的文件 * callBack:文件上傳后的回調函數 */ function uploadFiles(imgPaths, index, successFiles, callBack) { var that = this; wx.showLoading({ title: '正在上傳第' + index + '張', }) wx.uploadFile({ url: "http://10.109.86.1:5300/education/api/education/ImageUploader", filePath: imgPaths[index], name: 'anqindayviews', header: { "Content-Type": "multipart/form-data" }, success: function(res) { //成功,文件返回值存入成功列表 if (res && res.data) { var data = JSON.parse(res.data); if (data.isSuccess) { successFiles.push(data.content); } } }, complete: function(e) { index++; //下一張 if (index == imgPaths.length) { wx.hideLoading(); //上傳完畢,作一下提示 wx.showToast({ title: '上傳成功' + successFiles.length, icon: 'success', duration: 2000 }); if(callBack){ callBack(successFiles); } } else { //遞歸調用,上傳下一張 that.uploadFiles(imgPaths, index,successFiles, callBack); } } }) } module.exports = { uploader: uploader, uploadFiles: uploadFiles };
服務端C# webApi接收上傳數據,獲取文件數據,代碼如下:
var request = HttpContext.Current.Request;
HttpPostedFile file = request.Files["anqindayviews"];
到此,圖片上傳功能已經結束,下面開始介紹小程序組件封裝,這里采用Component來實現。
首先,在自己的代碼組織下建立component,其會自動生成類似常規頁面的相應文件,如下圖1、圖2所示。
圖一 新建組件 圖二 自動生成的文件目錄
下面直接代碼,邊看邊說。
.wxml文件
<!--component/uploader/upload.wxml-->
<view class="page__bd">
<view class="weui-cells">
<view class="weui-cell">
<view class="weui-cell__bd">
<view class="weui-uploader">
<view class="weui-uploader__hd">
<view class="weui-uploader__title">寶貝作品&照片上傳</view>
<view class="weui-uploader__info">{{files.length}}/{{maxFileCount}}</view>
</view>
<view class="weui-uploader__bd">
<view class="weui-uploader__files" id="uploaderFiles">
<block wx:for="{{files}}" wx:key="*this">
<view class="weui-uploader__file" bindlongpress="_deleteImage" data-index="{{index}}" bindtap="_previewImage" id="{{item.OrigionUrl}}">
<image class="weui-uploader__img" src="{{item.ZoomUrl}}" mode="aspectFill" />
</view>
</block>
</view>
<view style='display:{{isCanAddFile?"":"none"}}' class="weui-uploader__input-box">
<view class="weui-uploader__input" bindtap="_chooseImage"></view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
.json文件
{ "component": true, "usingComponents": {} }
.wxss文件 (注:這里使用小程序自帶樣式)
@import '../../style/weui.wxss';
.js文件
// component/uploader/upload.js var common = require("../../common/common.js"); Component({ options: { multipleSlots: true // 在組件定義時的選項中啟用多slot支持 }, /** * 組件的屬性列表 */ properties: { files: { type: Array, value: [] }, maxFileCount: { //允許最多9張圖片 type: Number, value: 9 }, isCanAddFile: { type: Boolean, value: true } }, /** * 組件的初始數據 */ data: { }, /* *組件生命周期函數,在組件布局完成后執行,此時可以獲取節點信息 */ ready: function () { }, /** * 組件的方法列表 */ methods: { /*圖片上傳 */ _chooseImage: function (e) { var that = this; wx.chooseImage({ count: that.data.maxFileCount - that.data.files.length, sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有 sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有 success: function (res) { // // 返回選定照片的本地文件路徑列表,tempFilePath可以作為img標簽的src屬性顯示圖片 var waitFiles = res.tempFilePaths; var allowCount = that.data.maxFileCount - that.data.files.length; //允許上傳的文件數 if (waitFiles.length >= allowCount) { waitFiles = waitFiles.slice(0, allowCount); } var index = 0; //第幾張開始 var successFiles = []; //成功的文件 common.uploadFiles(waitFiles, index, successFiles, function (urls) { //此處為抽出的公用方法,便於其它地方調用 that.data.files = that.data.files.concat(urls); if (that.data.files.length >= that.data.maxFileCount) { that.data.isCanAddFile = false; } that.setData({ files: that.data.files, isCanAddFile: that.data.isCanAddFile }); }); } }) }, /*圖片預覽*/ _previewImage: function (e) { var preUlrs = []; this.data.files.map( function (value, index) { preUlrs.push(value.OrigionUrl); } ); wx.previewImage({ current: e.currentTarget.id, // 當前顯示圖片的http鏈接 urls: preUlrs // 需要預覽的圖片http鏈接列表 }) }, /*圖片刪除*/ _deleteImage: function (e) { var that = this; var files = that.data.files; var index = e.currentTarget.dataset.index; //獲取當前長按圖片下標 wx.showModal({ title: '提示', content: '確定要刪除此圖片嗎?', success: function (res) { if (res.confirm) { files.splice(index, 1); } else if (res.cancel) { return false; } that.setData({ files, isCanAddFile: true }); } }) }, /*************供外部調用接口*******************/ getFiles: function () { return this.data.files; } } })
組件已經封裝好,經測試一切OK。
一切准備就緒,現在就該到使用了,驗證組件是否OK。
使用方法如下:
1、使用已注冊的自定義組件前,首先要在頁面的 json
文件中進行引用聲明。此時需要提供每個自定義組件的標簽名和對應的自定義組件文件路徑:
{
"usingComponents": {
"upload":"/component/uploader/upload"
}
}
這樣,在頁面的 wxml
中就可以像使用基礎組件一樣使用自定義組件。節點名即自定義組件的標簽名,節點屬性即傳遞給組件的屬性值。
2、頁面wxml使用:
<uploadid='upload'files='{{files}}'maxFileCount='{{maxFileCount}}'isCanAddFile='{{files.length>=maxFileCount?false:true}}'></upload>

點擊獲取文件,展示已有圖片列表。
整個多圖片上傳至服務器功能結束。
N久沒寫東東的我,寫完才覺得一團亂麻,看來以后要多多書寫,多多總結。