[组件封装]微信小程序-图片批量上传照片墙

描述

批量上传图片, 可设置最大上传个数, 可删除, 可设置默认值。

效果

源码

pictures-wall.wxml

<view class="picturesWall">
  <view class="picBox" wx:for="{{mydata}}" wx:key="{{index}}">
    <image class="pic" src="{{item.filePath || item.url}}" />    <view class="picDelete" data-index="{{index}}" bindtap="handleImageDelete">x</view>
  </view>
  <view class="picBox" wx:if="{{canUseCount > 0}}" bindtap="handleUpload">
    <view class="addicon"></view>
  </view>
</view>

pictures-wall.js

Component({
  properties: {
    mydata: Array,
    mymaxcount: Number,
  },

  data: {
    value: [],       // 暂存上传结果
    canUseCount: 0,  // 可使用个数
  },

  observers: {
    'mydata, mymaxcount': function (mydata, mymaxcount) {
      this.setData({ canUseCount: (mymaxcount || 3) - mydata.length });
    },
  },

  methods: {
    handleUpload: function () {
      const { canUseCount } = this.data;
      wx.chooseImage({
        count: canUseCount,
        success: (res) => {
          wx.showLoading();
          Promise.all(res.tempFilePaths.map(d => this.uploadFile(d)))
            .finally(() => {  // app.js中实现promise finally
              wx.hideLoading();
              this.triggerEvent('mychange', [...this.data.mydata, ...this.data.value]);
              this.data.value = [];  // 清空上传结果
            })
        }
      })
    },

    uploadFile: function (filePath) {
      return new Promise((resolve, reject) => {
        wx.uploadFile({
          url: '--url--',
          filePath,
          name: 'file',
          success: (res) => {
            if (res.statusCode === 200) {
              let json = JSON.parse(res.data);
              this.data.value.push({
                filePath,
                // 业务数据
              });
              resolve();
              return;
            }
            reject();
          },
          fail: (err) => {
            reject(err);
          }
        })
      })

    },

    handleImageDelete: function ({ currentTarget: { dataset: { index } } }) {
      const { mydata } = this.data;
      mydata.splice(index, 1);
      this.triggerEvent('mychange', mydata);
    },

  }

})

pictures-wall.wxss

.picBox {
  position: relative;
  display: inline-block;
  vertical-align: top;
  width: 208rpx;
  height: 208rpx;
  margin-right: 26rpx;
  margin-bottom: 26rpx;
  border-radius: 4rpx;
  border: 1px solid rgba(204,204,204,1);
}

.pic {
  width: 100%;
  height: 100%;
}

.picDelete {
  position: absolute;
  left: -32rpx;
  top: -32rpx;
  height: 64rpx;
  width: 64rpx;
  line-height: 64rpx;
  text-align: center;
}

.picturesWall .picBox:nth-child(3n) {
  margin-right: 0;
}

.addicon {
  position: absolute;
  display: inline-block;
  left: 104rpx;
  top: 54rpx;
  height: 100rpx;
  width: 0rpx;
  border-right: 1px solid #CCCCCC;
}
.addicon::after {
  content: '';
  position: absolute;
  top: 50rpx;
  left: -50rpx;
  display: block;
  height: 0rpx;
  width: 100rpx;
  border-bottom: 1px solid #CCCCCC;
}

pictures-wall.json

{
  "component": true,
  "usingComponents": {}
}

app.js

由于微信小程序Promise finally, 所以要在app.js里实现一下。

App({
  onLaunch: function () {
    // finally
    Promise.prototype.finally = function (callback) {
      let P = this.constructor;
      return this.then(
        value => P.resolve(callback()).then(() => value),
        reason => P.resolve(callback()).then(() => { throw reason })
      );
    };
  },

  globalData: {
    
  }
})

使用例子

test.wxml

<pictures-wall mydata="{{picList}}" mymaxcount="{{9}}" bindmychange="handlePicturesChange" />
<pictures-wall mydata="{{picList1}}" mymaxcount="{{9}}" bindmychange="handlePicturesChange1" />

test.js

Page({
  data: {
    picList: [],
    picList1: [{url: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1567767650570&di=e99314caaadc830e9b590311945cdbaa&imgtype=0&src=http%3A%2F%2Fimages.liqucn.com%2Fh027%2Fh13%2Fimages201508311321540_info200X200.png'}],
  },

  handlePicturesChange: function ({ detail }) {
    this.setData({ picList: detail })
  },
handlePicturesChange1: function ({ detail }) {
  this.setData({ picList1: detail })
},})

test.json

{
  "navigationBarTitleText": "demo",
  "usingComponents": {
    "pictures-wall": "/components/pictures-wall/pictures-wall"
  }
}

猜你喜欢

转载自www.cnblogs.com/whosMeya/p/12557313.html