微信小程序多张图片上传组件

作者: 独孤久见 | 来源:发表于2018-10-27 14:50 被阅读61次

    在实际开发中,很多时候都需要要上传图片,但是对于上传多张时需要一张张的上传,因为图片都可能比较大,这时就需要我们对上传图片的API进行进一步的处理,这样就解决了我们同时选择上传多张图片需求。所以为了方便以后使用,封装成一个特定的组件分享出来,也许很多能用到,也可能用不到,但是修改一下还是差不多一样可以用的。

    一.实现原理

    多张图片上传的原理其实就是用递归的方法,在每一张上传完之后再继续上传下一张,直到完成为止。

    二.效果

    微信小程序多张图片上传效果

    三.实现过程

    新建一个uploadImages组件文件,定义组件的样式结构及js文件。
    1.页面样式布局
    view

    <view class='content'>
      <view class='img-box'>
        <view class='img-list'>
          <block wx:for="{{detailPics}}" wx:key="index">
            <view class='img-item'>
              <image src='{{item}}' bindlongpress="bindlongpressimg" data-id='{{index}}'></image>
            </view>
          </block>
          <view class='chooseimg' bindtap='uploadDetailImage'>
            <view class="weui-uploader__input-box"></view>
          </view>
        </view>
        <view class='tips'>长按对应的图片即可删除</view>
      </view>
    </view>
    

    css

    .content {
      width: 100%;
      background-color: #fff;
    }
    
    .img-list {
      display: flex;
      display: -webkit-flex;
      flex-direction: row;
      justify-content: flex-start;
      align-items: center;
      flex-wrap: wrap;
    }
    
    .img-item {
      width: 30%;
      text-align: left;
      margin-right: 20rpx;
      margin-bottom: 10rpx;
    }
    
    .img-item image {
      width: 180rpx;
      height: 180rpx;
    }
    
    .submit-btn {
      width: 100%;
      background-color: #fff;
      height: 80rpx;
      text-align: center;
      line-height: 80rpx;
      font-size: 30rpx;
      position: fixed;
      bottom: 100rpx;
    }
    
    .chooseimg {
      background-color: #fff;
    }
    
    .weui-uploader__input-box {
      float: left;
      position: relative;
      margin-right: 9px;
      margin-bottom: 9px;
      width: 180rpx;
      height: 180rpx;
      border: 1px solid #d9d9d9;
    }
    
    .weui-uploader__input-box:before {
      width: 2px;
      height: 39.5px;
    }
    
    .weui-uploader__input-box:after, .weui-uploader__input-box:before {
      content: " ";
      position: absolute;
      top: 50%;
      left: 50%;
      -webkit-transform: translate(-50%, -50%);
      transform: translate(-50%, -50%);
      background-color: #d9d9d9;
    }
    
    .weui-uploader__input-box:after {
      width: 39.5px;
      height: 2px;
    }
    
    .weui-uploader__input-box:after, .weui-uploader__input-box:before {
      content: " ";
      position: absolute;
      top: 50%;
      left: 50%;
      -webkit-transform: translate(-50%, -50%);
      transform: translate(-50%, -50%);
      background-color: #d9d9d9;
    }
    
    .tips {
      color: #666;
      font-size: 24rpx;
      padding-bottom: 20rpx;
    }
    
    .img-box {
      width: 92%;
      margin: auto;
      padding-top: 20rpx;
    }
    

    2.实现逻辑

    // component/uploadImages/index.js
    Component({
      /**
       * 组件的属性列表
       */
      properties: {
        count: { //最多选择图片的张数,默认9张
          type: Number,
          value: 9
        },
        uploadUrl: { //图片上传的服务器路径
          type: String,
          value: ''
        },
        showUrl: { //图片的拼接路径
          type: String,
          value: ''
        }
      },
    
      /**
       * 组件的初始数据
       */
      data: {
        detailPics: [], //上传的结果图片集合
      },
    
      ready: function() {
        console.log(this.data)
      },
    
      /**
       * 组件的方法列表
       */
      methods: {
    
        uploadDetailImage: function(e) { //这里是选取图片的方法
          var that = this;
          var pics = [];
          var detailPics = that.data.detailPics;
          if (detailPics.length >= that.data.count) {
            wx.showToast({
              title: '最多选择' + that.data.count + '张!',
            })
            return;
          }
          wx.chooseImage({
            count: that.data.count, // 最多可以选择的图片张数,默认9
            sizeType: ['original', 'compressed'], // original 原图,compressed 压缩图,默认二者都有
            sourceType: ['album', 'camera'], // album 从相册选图,camera 使用相机,默认二者都有
            success: function(res) {
              var imgs = res.tempFilePaths;
              for (var i = 0; i < imgs.length; i++) {
                pics.push(imgs[i])
              }
              that.uploadimg({
                url: that.data.uploadUrl, //这里是你图片上传的接口
                path: pics, //这里是选取的图片的地址数组
              });
            },
          })
    
        },
        //多张图片上传
        uploadimg: function(data) {
          wx.showLoading({
            title: '上传中...',
            mask: true,
          })
          var that = this,
            i = data.i ? data.i : 0,
            success = data.success ? data.success : 0,
            fail = data.fail ? data.fail : 0;
          wx.uploadFile({
            url: data.url,
            filePath: data.path[i],
            name: 'fileData',
            formData: null,
            success: (resp) => {
              wx.hideLoading();
              success++;
              var str = resp.data //返回的结果,可能不同项目结果不一样
              var pic = JSON.parse(str);
              var pic_name = that.data.showUrl + pic.Data;
              var detailPics = that.data.detailPics;
              detailPics.push(pic_name)
              that.setData({
                detailPics: detailPics
              })
            },
            fail: (res) => {
              fail++;
              console.log('fail:' + i + "fail:" + fail);
            },
            complete: () => {
              i++;
              if (i == data.path.length) { //当图片传完时,停止调用     
                console.log('执行完毕');
                console.log('成功:' + success + " 失败:" + fail);
                var myEventDetail = {
                  picsList: that.data.detailPics
                } // detail对象,提供给事件监听函数
                var myEventOption = {} // 触发事件的选项
                that.triggerEvent('myevent', myEventDetail, myEventOption)//结果返回调用的页面
              } else { //若图片还没有传完,则继续调用函数
                data.i = i;
                data.success = success;
                data.fail = fail;
                that.uploadimg(data);//递归,回调自己
              }
            }
          });
        },
    
      }
    })
    

    3.使用自定义组件

    (1) 在json文件中
    {
      "usingComponents": {
        "uploadImages": "/component/uploadImages/index"
      }
    }
    
    (2) 在view中
    <uploadImages bindmyevent="myEventListener" count='{{countPic}}' showUrl="{{showImgUrl}}" uploadUrl="{{uploadImgUrl}}"></uploadImages>
    
    (3) 在js中
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        countPic:9,//上传图片最大数量
        showImgUrl: "", //路径拼接,一般上传返回的都是文件名,
        uploadImgUrl:''//图片的上传的路径
      },
      
      //监听组件事件,返回的结果
      myEventListener:function(e){
       console.log("上传的图片结果集合")
       console.log(e.detail.picsList)
      },
      
    })
    

    图片插件这样大概就完成了,不过不是每一个人都是和我一样的情况,使用请具体项目分析。
    实例请查看地址:https://github.com/kingbuwu/uploadImages

    相关文章

      网友评论

        本文标题:微信小程序多张图片上传组件

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