• 微信小程序-上传多张图片加进度,持续修正中……


    tips.参考网上资料的改进版

    1.怎么使用.html

             <!-- 无限制需要在js代码里设置数量,upload为上传地址,或者说图片服务器 -->
              <up-pic url="{{upload}}" bindupImgData="upImgData" class='up-pic' notli/>
              <!-- 或者:限制只能少于9 -->
              <up-pic url="{{upload}}" bindupImgData="upImgData" count="8" class='up-pic'/>         

    1.2.怎么使用.js

      // 上传图片返回
      upImgData(e) {
        // console.log(e.detail)
        this.setData({
          images: e.detail
        })
      },

    1.3.怎么使用.json

    {
      "usingComponents": {
        "up-pic": "./up-pic/index"
      }
    }

    2.核心组件代码

    /up-ipc/

    ./up-ipc/index.js

    /**
     * <up-pic url="{{upload}}" count="3" autoup class='up-pic'></up-pic>
     * 
     * url:上传图片地址
     * count:上传总数量(默认上传1张图片)
     * autoup:是否自动上传(无需传参数,参考以上)
     * 2019-04-15 MIT
     */
    import { promisify } from '../../../../utils/promise'
    const wxUploadFile = promisify(wx.uploadFile)
    const network = require("../../../../utils/upload.js")
    Component({
    
      data: {
        imgs: [],
        upload_picture_list: [],
        count: 1,
        url: '',
        notli: false
      },
      properties: {
        url: {
          type: String,
          observer(newVal, oldVal) {
            this.data.url = newVal;
          }
        },
        count: {
          type: Number,
          observer(newVal, oldVal) {
            this.data.count = newVal;
          }
        },
        notli: {
          type: Boolean
        }
      },
    
      methods: {
        chooseImage() {
          cImage(this, parseInt(this.data.count), this.data.url);
        },
        uploadimage() {
          uImage(this, this.data.url);
        },
        deleteImg(e) {
          dImage(e, this);
        },
        previewImg(e) {
          pImage(e, this);
        }
      }
    
    })
    
    
    // 上传图片(this,api.imageup)
    const uImage = (_that, url) => {
      // console.log(_that.data.upload_picture_list)
    
      uploadFileServer(url, _that, _that.data.upload_picture_list)
    }
    
    const uploadFileServer = (url, that, upload_picture_list) => {
      const upload = promisify(network.upload)
      //上传
    
      const promises = upload_picture_list.map(function (item) {
        // console.log(item)
        if (item.path_server !== '') return;
        return upload({
          url: url,
          path: item['path'],
          name: 'file',
          extra: {},
          myfn (data) {
            item.path_server= data.result
            that.setData({
              upload_picture_list: upload_picture_list
            });
            let images = that.data.upload_picture_list.map(e => e.path_server)
            that.setData({
              images: images
            });
            that.triggerEvent('upImgData', images);
          },
          progress (res) {
            // console.log('上传进度', res.progress)
            item.upload_percent = res.progress
            that.setData({
              upload_picture_list: upload_picture_list
            });
          }
        })
      })
      
    }
    
    
    // 删除图片
    const dImage = (e, _that) => {
      _that.data.upload_picture_list.splice(e.currentTarget.dataset.index, 1);
      _that.data.imgs.splice(e.currentTarget.dataset.index, 1);
      _that.setData({
        upload_picture_list: _that.data.upload_picture_list
      });
      let images = _that.data.upload_picture_list.map(e => e.path_server)
      _that.setData({
        images: images
      });
      _that.triggerEvent('upImgData', images);
    }
    
    
    // 选择图片
    const cImage = (_that, count, url) => {
      wx.chooseImage({
        count: _that.data.notli ? count = 20 : count,
        sizeType: ['original', 'compressed'],
        sourceType: ['album', 'camera'],
        success: function(res) {
          _that.data.imgs = _that.data.imgs.concat(res.tempFilePaths)
          for (let i in res.tempFiles) {
            res.tempFiles[i]['upload_percent'] = 0
            res.tempFiles[i]['path_server'] = ''
            _that.data.upload_picture_list.push(res.tempFiles[i]);
            _that.data.upload_picture_list.length > count ? _that.data.upload_picture_list = _that.data.upload_picture_list.slice(0, count) : console.log();
          }
          !_that.data.notli && count == _that.data.upload_picture_list.length ? uImage(_that, url) : console.log();
          _that.data.notli && count == 20 ? uImage(_that, url) : console.log();
          _that.data.notli ? console.log(`%c 开启无限制上传图片模式(单次选择最多20张)`, `color:#f00;font-weight:bold;`) : console.log(`%c 开启限制上传图片模式,目标数量为:${count}`, `color:#f00;font-weight:bold;`);
          _that.data.upload_picture_list = _that.data.upload_picture_list.slice(0, count);
          _that.setData({
            upload_picture_list: _that.data.upload_picture_list,
          });
          // console.log(_that.data.upload_picture_list)
        }
      })
    }
    
    // 预览图片
    const pImage = (e, _that) => {
      let percent = e.currentTarget.dataset.percent
      if (percent === '1') {
        wx.previewImage({
          current: _that.data.images[e.currentTarget.dataset.index],
          urls: _that.data.images
        })
      } else {
        wx.previewImage({
          current: _that.data.imgs[e.currentTarget.dataset.index],
          urls: _that.data.imgs
        })
      }
      
    }

    ./up-ipc/index.json

    {
      "component": true
    }

    ./up-ipc/index.wxml

    <view class='sunsin'>
      <view class="sunsin_picture_list">
        <view wx:for="{{upload_picture_list}}" class="sunsin_picture_item" wx:key="{{index}}">
          <image wx:if="{{item.upload_percent < 100}}" src="{{item.path}}" mode="aspectFill"></image>
          <image wx:if="{{item.upload_percent == 100}}"  data-index="{{index}}" src="{{item.path_server}}" mode="aspectFill" bindtap="previewImg" data-percent="1"></image>
          <view class="sunsin_upload_progress" wx:if="{{item.upload_percent < 100}}" data-index="{{index}}" bindtap="previewImg" data-percent="0">{{item.upload_percent}}%</view>
          <text class='del' bindtap='deleteImg' data-src='{{image}}' style='display:{{isDel}}' data-index="{{index}}">×</text>
        </view>
        <view class='sunsin_picture_item' wx:if="{{upload_picture_list.length<count || notli}}">
          <view class="sunsin-add-image" bindtap='chooseImage'>
            <text class='iconfont icon-tupianshangchuan'></text>
          </view>
        </view>
      </view>
    </view>

    ./up-ipc/index.wxss

    @import "iconfont";
    
    image {
      width: 40rpx;
      height: 40rpx;
      margin: 0 4%;
    }
    
    .icon-tupianshangchuan {
      font-size: 73rpx;
    }
    
    .sunsin_picture_list {
      width: 100%;
      padding: 20rpx;
      display: flex;
      flex-wrap: wrap;
      align-items: flex-start;
      align-content: flex-start;
      flex-direction: row;
      justify-content: flex-start;
    }
    
    .sunsin_picture_list image {
      width: 40rpx;
      height: 40rpx;
      margin: 0 4%;
    }
    
    .sunsin-add-image {
      width: 150rpx;
      height: 150rpx;
      color: #ddd;
      font-size: 144rpx;
      line-height: 62%;
      text-align: center;
      margin: 2% 0 0 2%;
      background-color: #eee;
      cursor: pointer;
      border-radius: 10rpx;
    }
    
    .sunsin_picture_item {
      margin: 20rpx;
      margin-left: 0;
      position: relative;
      width: 160rpx;
      height: 160rpx;
    }
    
    .sunsin_picture_item .del {
      position: absolute;
      top: 0;
      right: -6rpx;
      color: #fff;
      border-radius: 4rpx;
      width: 40rpx;
      height: 40rpx;
      line-height: 40rpx;
      z-index: 2;
      text-align: center;
      background-color: #e54d42;
    }
    
    .sunsin_upload_progress {
      font-size: 24rpx;
      color: #fff;
      width: 167rpx;
      height: 160rpx;
      text-align: center;
      line-height: 160rpx;
      position: absolute;
      top: 0;
      left: 0;
      opacity: 0.7;
      border-radius: 8rpx;
      background-color: #000;
    }
    
    .sunsin_picture_item image {
      width: 160rpx;
      height: 160rpx;
      border-radius: 3px;
    }
    
    .sunsin-yes-upload {
      color: #fff;
      border-radius: 0;
      background-color: #00a0e9;
    }

    ./up-ipc/iconfont.wxss

    @font-face {font-family: "iconfont";
      src: url('iconfont.eot?t=1552565213642'); /* IE9 */
      src: url('iconfont.eot?t=1552565213642#iefix') format('embedded-opentype'), /* IE6-IE8 */
      url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAANIAAsAAAAAB0AAAAL6AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcAqCQIIXATYCJAMICwYABCAFhG0HOhtHBhHVmz3IfibYjlEWYEvmdtInlWCZnjPBw2dX/arqwXWvwOwsL8yXn5lBjqcBAujAB8DmZugaFaFYkvO8n74jHRPS8MMn7p3+lvh8QDmOtWmsSV2A8daA9sYoobRAAvO4YeyCF3gbAtAJEEcMHT52KlY07EUCEGtXrViEtaBF60gXWBGYG3ZqiFxMWOUpeQfIiT4vvpKSFSQmhZ01cfmwpQz8UOVEqYO2g3MDAt5yZoDtAwXEAQ3E1EbreFQSiKPQ9YBGCI6VLuBDlc0WcA/7wwMBwoydageAH+Q+E8/jP2qRBEDj2QdXAtsnvRSYvBzt/bz2FJ92m1p4sC3DcwBFbU0dQvQryug45LG8oj6m/VpYYy9VD9Mzbk8/5FlSYmS0HSx1O92+wanxjJdWdjbcUTgUtwvToQ7DMaMNaajyc1uLMjxnTMswmiJXlBxqP+22dHpx4+z/oCz1YcxJ35OzZp3yDvEuDblmyAs4XltW5h3qfco2tr0lfVpba+cbf0vqRv+Etf3sSz2uWuyDvP5eckxa8IPaVP2gnlobNJBX0m6gvXS84Cjtawde0FPfrSz1Lj1+fPNmIWPi+/Yt80r1LgsP37ytZGJZTc0qKwMBsF1dUEF//jus3RfdusCx73+roQHwqHfp82iO7RoqCLDen03Af+YNbNAMga2TmsZrjEhWYrr/Mh0dsMFOFy+mKt1fyiywFngMEgv+UFgJI2m0OJgwSIMZKwOgE2vEfgNXm1EIrQ8Q4xiAwEkPJA6ch8LJXZJGew4THr7DjFMKOtOF64kGEZlBDCGUjAbUH4Ju1boGFnH6Hd2VJeUFEf2N1IMblnEuh29YkZZY0z9uZbZgqRXYwX2Yc4ODWkTNo2c+tmmyTU8adSuDMIRQMhqg/iDoVm3QmkXl/Xd0V5bUUVfnfCP1MDxYjOYBpJu0Dqp7lEf6x62YLbDUCtjBNMy5gaN5WkTNIz/Bd2wmp5kdKh23l5e/2wbobJXMGaVw2nUEWbv3XE77K9AMAwAA') format('woff2'),
      url('iconfont.woff?t=1552565213642') format('woff'),
      url('iconfont.ttf?t=1552565213642') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
      url('iconfont.svg?t=1552565213642#iconfont') format('svg'); /* iOS 4.1- */
    }
    
    .iconfont {
      font-family: "iconfont" !important;
      font-size: 16px;
      font-style: normal;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    
    .icon-tupianshangchuan:before {
      content: "e69d";
    }

    3.补充api封装

    upload.js

    function upload(options) {
      var url = options.url,
        path = options.path,
        name = options.name,
        // data = options.data,
        extra = options.extra,
        success = options.success,
        progress = options.progress, // progress 方法
        fail = options.fail,
        myfn = options.myfn
      const uploadTask = wx.uploadFile({
        url: url,
        filePath: path,
        name: name,
        formData: extra,
        success: function(res) {
          // console.log(res);
          var data = res.data
          try {
            data = JSON.parse(res.data)
            // console.log(data)
          } catch (e) {
            console.log(data)
            throw (e)
          }
          if (res.statusCode == 200) {
            if (success) {
              // console.log(data)
              success(data)
              myfn(data)
            }
          } else {
            if (fail) {
              fail(data)
            }
          }
        },
        fail: function(res) {
          console.log(res)
          if (fail) {
            fail(res)
          }
        }
      })
    
      uploadTask.onProgressUpdate((res) => {
        // console.log('上传进度', res.progress)
        // console.log('已经上传的数据长度', res.totalBytesSent)
        // console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend)
        if (progress)(
          progress(res)
        )
      })
    }
    
    module.exports = {
      upload: upload
    }

    promise.js

    /**
     * 将wx的callback形式的API转换成支持Promise的形式
     */
    module.exports = {
    
      promisify: api => {
        return (options, ...params) => {
          return new Promise((resolve, reject) => {
            const extras = {
              success: resolve,
              fail: reject
            }
            api({ ...options, ...extras }, ...params)
          })
        }
      }
    
    }

     4.demo

  • 相关阅读:
    docker初识--简单用法
    性能测试--面向目标场景设计
    性能测试之--波浪场景设计
    性能测试之--阶梯负载场景设计
    Jmeter后置处理器之正则提取器详解
    JMETE-元件执行顺序
    python高阶函数-map、reduce、filter
    socket 多线程安全、粘包问题
    The fastest MySQL Sandbox setup ever!
    两个实用的Python的装饰器
  • 原文地址:https://www.cnblogs.com/yuqlblog/p/10709058.html
Copyright © 2020-2023  润新知