小程序多图片上传组件封装及使用

  最近刚开发了小程序上传图片功能,为了便于后续查找,特此记录归总。

     在实际开发过程中,图片上传功能是很常用的功能,所以将其封装成组件,避免后续重复劳动力,已是不争的事实。

  一、先将图片上传功能能封装成公用模块(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
};
View Code

   服务端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/upload.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 >
<button bindtap='showFiles'>获取文件</button>
3、页面js:

Page({
data: {
files: [
],
maxFileCount: 10
},
onReady: function() {
//获得upload组件,后续直接用upload调用组件方法
this.upload = this.selectComponent( "#upload");
},
})
 
4、获取已上传文件列表,在页面js中定义showFiles,show出文件列表。
showFiles: function() {
this.data.files = this.upload.getFiles(); //调用组件外显方法,获取文件列表
console.log( this.data.files);
}
 
效果图:

点击获取文件,展示已有图片列表。

整个多图片上传至服务器功能结束。

N久没写东东的我,写完才觉得一团乱麻,看来以后要多多书写,多多总结。

猜你喜欢

转载自www.cnblogs.com/Sarah-Dora/p/9257789.html