美文网首页
小程序开发之三(upload封装)

小程序开发之三(upload封装)

作者: CallMeSoul | 来源:发表于2017-11-10 17:34 被阅读453次

    磨刀不误砍柴工。这节我们来封装下图片上传,文件上传类似。只是我的业务暂不涉及到文件上传

    wx.chooseImage(OBJECT)

    上传之前当然要选上传的文件。

    小程序的上传业务是这个样的

    1. wx.chooseImage选择要上传的文件,会生成对应的临时path
    2. 可以拿这些临时path去上传或者预览。

    wx.chooseImage提供的参数比较多:

    参数 类型 必填 说明
    count Number 最多可以选择的图片张数,默认9
    sizeType StringArray original 原图,compressed 压缩图,默认二者都有
    sourceType StringArray album 从相册选图,camera 使用相机,默认二者都有
    success Function 成功则返回图片的本地文件路径列表 tempFilePaths
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    为了使用简单点,我们先来封装下wx.chooseImage:

    chooseImage: function ({sizeType = ['compressed'], sourceType = ['album', 'camera'], count = 9}){
        return new es6.Promise((resolve,reject)=>{
          wx.chooseImage({
            count: count, // 默认9
            sizeType: sizeType, // 可以指定是原图还是压缩图,默认压缩图
            sourceType: sourceType, // 可以指定来源是相册还是相机,默认二者都有
            success: function (res) {
              // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
              resolve(res.tempFilePaths);
            },
            fail:function(error){
              reject(error)
            }
          })
        });
      },
    

    上面代码我们默认了,最多选{9}张,sizeType是{compressed}压缩后的图片,sourceType是{'album', 'camera'}相机和相册。这样我们就不用填任何参数,直接调用即可,就会使用默认的这些参数。

    如果你需要定制参数,比如需要上传原图。你只要参对应参数即可,如:

    chooseImage({sizeType:['original ']})

    这样就会覆盖了默认的参数。

    注意:参数格式必须数组格式,因为要wx.chooseImage的参数格式对应。

    wx.uploadFile(OBJECT)

    将本地资源上传到开发者服务器,客户端发起一个 HTTPS POST 请求,其中 content-typemultipart/form-data

    如页面通过 wx.chooseImage 等接口获取到一个本地资源的临时文件路径后,可通过此接口将本地资源上传到指定服务器。

    OBJECT参数说明:

    参数 类型 必填 说明
    url String 开发者服务器 url
    filePath String 要上传文件资源的路径
    name String 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容
    header Object HTTP 请求 Header, header 中不能设置 Referer
    formData Object HTTP 请求中其他额外的 form data
    success Function 接口调用成功的回调函数
    fail Function 接口调用失败的回调函数
    complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

    很明显filePath为string,wx.uploadFile每次只能上传一个文件。我们选了多张图片,你却只能一次上一个?

    很明显是小程序的框架还没时间做到很完善。只是提供了基本的接口。其他丰富的就留回给开发者自己封装开发。就像这篇文章。

    所以这个的上传是多文件上传封装。因为多文件上传兼容单文件上传,单文件上传只需数组传一个。上传完拿结果数组的第一个即可。

    uploadImage: function ({ files = [], name = 'file', formData = {}, header = {}, dir = '',url=config.uploadImageUrl}){
        return new es6.Promise((resolve,reject)=>{
          if (files && files instanceof Array && files.length>0){
            var promiseList=[];
            for (var i = 0; i < files.length;i++){
              promiseList[i] =  new es6.Promise((resolve, reject) => {
                wx.uploadFile({
                  url: url + dir, //仅为示例,非真实的接口地址
                  filePath: files[i],
                  name: name,
                  formData: formData,
                  header: header,
                  success: function (res) {
                    resolve(res.data);
                  },
                  fail: function (error) {
                    reject(error);
                  }
                })
              });
            }
            es6.Promise.all(promiseList)
              .then(function (result){
                resolve(result);
              })
              .then(function(error){
                reject(error);
              })
          }else{
            reject('传参有误,请传数组格式');
          }
        })
      }
    

    原理主要是每个请求按顺序装在一个数组里。然后用Promise.all批处理同时上传,上传后按照上传时的顺序返回结果。大家可以去看看es6的promise。

    完整代码如果:

    import config from '../config.js'
    import es6 from '../lib/es6-promise.min.js'
    
    let upload={
      chooseImage: function ({sizeType = ['compressed'], sourceType = ['album', 'camera'], count = 9}){
        return new es6.Promise((resolve,reject)=>{
          wx.chooseImage({
            count: count, // 默认9
            sizeType: sizeType, // 可以指定是原图还是压缩图,默认压缩图
            sourceType: sourceType, // 可以指定来源是相册还是相机,默认二者都有
            success: function (res) {
              // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
              resolve(res.tempFilePaths);
            },
            fail:function(error){
              reject(error)
            }
          })
        });
      },
      /**
       * 以wx.request作为底层方法
       * @param {arr}     files         图片url集合
       * @param {String}  url           图片上传接口地址
       * @param {String}  dir           上传目录地址
       * @param {String}  name          文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容
       * @param {Object}  header        HTTP 请求 Header, header 中不能设置 Referer
       * @param {Object}  formData      HTTP 请求中其他额外的 form data
       */
      uploadImage: function ({ files = [], name = 'file', formData = {}, header = {}, dir = '',url=config.uploadImageUrl}){
        return new es6.Promise((resolve,reject)=>{
          if (files && files instanceof Array && files.length>0){
            var promiseList=[];
            for (var i = 0; i < files.length;i++){
              promiseList[i] =  new es6.Promise((resolve, reject) => {
                wx.uploadFile({
                  url: url + dir, //仅为示例,非真实的接口地址
                  filePath: files[i],
                  name: name,
                  formData: formData,
                  header: header,
                  success: function (res) {
                    resolve(res.data);
                  },
                  fail: function (error) {
                    reject(error);
                  }
                })
              });
            }
            es6.Promise.all(promiseList)
              .then(function (result){
                resolve(result);
              })
              .then(function(error){
                reject(error);
              })
          }else{
            reject('传参有误,请传数组格式');
          }
        })
      }
    }
    
    export default upload;
    

    使用

    现在app.js全局引入:

    import Upload from './untils/upload.js'
    App({
      onLaunch: function () {
        //......
      },
      Upload:Upload,
    })
    

    然后就可以在page的每个页面使用了:

    const app = getApp()
    app.Page({
      data: {
        
      }, 
      onLoad: function () {
        app.Upload.chooseImage({ sizeType: ['original', 'compressed'], count:2}).then(function(files){
          app.Upload.uploadImage({'files':files}).then(function(result){
            console.log(result);
          });
        });
      }
    });
    

    是不是方便多了。

    文档使用markdown编写。希望公众平台尽快可以兼容markdown。

    markdown在手,天下我有。

    原文链接

    未标题-1.jpg

    相关文章

      网友评论

          本文标题:小程序开发之三(upload封装)

          本文链接:https://www.haomeiwen.com/subject/wuximxtx.html