0


【Vant Weapp】van-uploader 文件上传

图片上传

未上传样式:

上传限制6张后 :

<van-uploader 
      max-count="6" 
      file-list="{{ fileList }}" 
      bind:after-read="afterRead" 
      bind:delete="delete"
      multiple="{{true}}" 
      upload-text='上传图片' 
/>

fileList的图片要求的是全路径(http://xxxxx.com/xxxxx.png),而后端要求是去除域名(xxxxx.png),所以我另外封装了一个imgs数组。

data: {
    fileList: [], 
    imgs: [], 
    baseUrl:"http://xxxxx.com"
}
afterRead(event) {
  const { file } = event.detail;
  let that = this
  // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
  wx.uploadFile({
    url: 'http:xxxxx.com/upload',
    filePath: file[0].url,
    name: 'files',
    header: {
      "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
    },
    formData: {},
    success: function (res) {

      // http://xxxxx.com/xxxxx.png
      const fileList = [...that.data.fileList]
      const url = 'http:xxxxx.com' + JSON.parse(res.data).data[0]
      fileList.push({url}) 

      // /xxxxx.png
      const imgs = [...that.data.imgs]
      imgs.push(JSON.parse(res.data).data[0]) 
      
      that.setData({
        imgs,
        fileList
      })
    },
  })
},

// 删除图片
delete(e) {
  let idx = e.detail.index

  let fileList = this.data.fileList
  fileList.splice(idx, 1)

  let imgs = this.data.imgs
  imgs.splice(idx, 1)
  
  this.setData({
    fileList,
    imgs
  })
},

图片回填

进入页面onload就要去调取接口,获取回填的数据。getPicture是获取数据的接口,可以自行换成自己的。

后台返回:

[
  {
    img:'/xxx.png',
    name:'xxx'
  }
]

fileList需要的是:

[
  {
    url:'/xxx.png',
    name:'xxx'
  }
]
onLoad() {
    getPicture({
      id: this.data.id,
    }).then(res => {
      let imgs = []
      res.data.forEach((v) => {
        v.url = v.img // 接口中返回的名称,但是控件要求是url
        
        // 获取没有域名(/xxxxx.png)的数据。
        var reg = new RegExp(baseUrl,"g"); 
        var url = v.img.replace(reg,"");
        imgs.push(url)
      });
      this.setData({
        imgs,
        fileList: res.data
      })
    })
}

修改样式

/*上传框*/
.van-uploader .van-uploader__wrapper .van-uploader__upload {
  width: 160rpx !important;
  height: 160rpx !important;
}

/*小相机*/
.van-uploader__upload-icon {
  font-size: 80rpx !important;
}

循环多个上传图片

问题:由于afterRead无法传参,所以我在父级节点上添加点击事件。

<view class="list">
  <view class="item" wx:for-items="{{list}}" wx:key="index">
    <view class="box" data-index="{{index}}" bind:tap="up">
      <van-uploader 
        preview-size="200rpx" 
        max-count="3" 
        file-list="{{item.fileList}}" 
        bind:after-read="afterRead"
        bind:delete="delete" 
        multiple="{{true}}" 
        upload-text='上传图片' 
      />
    </view>
  </view>
</view>

第一步:初始化的时候给list每一项添加fileList数组

onLoad: function (options) {
  this.getList()
},

getList() {
  let id = this.data.id
  getList({ id }).then(res => {
    let list = res.data
    if(list && list.length>0) {
      list.forEach((v,k)=>{
        v.fileList = []
      })
    }
    this.setData({
      list
    })
  }).catch(err => {
    console.log(err)
  })
},

第二步:得到点击时的index

up (e) {
  this.setData({
    idx: e.currentTarget.dataset.index
  })
},

第三步:上传成功后,压缩图片并且上传服务器。上传成功后,找到第index个fileList塞入图片。

afterRead(event) {
  const that = this
  const { file} = event.detail; 

  // 压缩图片
  wx.compressImage({ 
    src: file[0].url, //路径
    quality: 70, // 质量
    compressedWidth: 600,
    success(res){

      // 上传服务器
      wx.uploadFile({
        url: `http:xxxxx.com/commons/upload`,
        filePath: res.tempFilePath,//相当于file[0].url,
        name: 'files',
        header: {
          "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
        },
        formData: {},
        success: function (res) {
          const list = that.data.list
          const fileList = list[that.data.idx].fileList
          fileList.push({
            url: 'http://xxxxx.com' + JSON.parse(res.data).data[0],
            name: '1'
          })
          that.setData({
            taskInfo: list
          })
        },
        fail: function (res) {}
      })

    },
  })
},

第四步:设置删除图片

delete(e) {
  let that = this
  let index = e.detail.index
  const list = that.data.list
  const fileList = list[that.data.idx].fileList
  fileList.splice(index, 1)
  this.setData({
    list: list
  })
},

自定义上传的控件

需求是点击右侧的加号,新增的图片在下方区域展示。

问题一:

第一步:参考Vant Weapp - uploader中自定义上传样式。将按钮改成加号图片。

<view class="list">
    <view class="item" wx:for-items="{{list}}" wx:key='index'  data-item='{{item}}'>

      <!-- 上传图片区域 -->
      <view class="box" style="display: flex; align-items: center;">
        <view class="name"  style="margin-left: 10rpx">图片</view>
        <van-uploader max-count="3" file-list="{{ item.fileList }}" bind:after-read="afterRead" bind:delete="delete" data-item="{{item}}" data-index="{{index}}">
          <image class="add" src="../../assets/images/add.png"></image>
        </van-uploader>
      </view>

      <!-- 图片展示区域 -->
      <view class="img_list">
        <view class="img_box" wx:for-items="{{item.imgData}}" wx:key="item" wx:for-index="k" wx:for-item="v">
          <!-- 删除按钮 -->
          <van-icon name="clear" class="close" catchtap='deleteImg' data-k="{{k}}" data-v="{{v}}" data-item="{{item}}" data-index="{{index}}"/>
          <!-- 图片 -->
          <image class="img" mode="aspectFit" src="{{'http://www.xxxx.com'+v}}" data-src="{{'http://www.xxxx.com'+v}}" data-item="{{item}}" alt="图片"/>
        </view>
      </view>
      
    </view>
  </view>

第二步:上传图片后,控件默认上传后展示图片在加号的前面。

这就导致了位置有偏移。最后只能自定义一个图片展示区域了。隐藏默认图片展示

.van-uploader__preview {
  display: none!important;
}

第三步:初始化给每一项都添加fileList和imgList

onLoad: function (options) {
  this.getList()
},
getList() {
  getList({id}).then(res => {
    res.data.forEach((v)=>{
      v.fileList = []
      v.imgData = []
    })
    this.setData({
      list: res.data
    })
  })
}

第四步:将上传成功的图片回填

afterRead(event) {
  const that = this
  const { file} = event.detail; 
  
  let index = that.data.index

  wx.uploadFile({
    url:'http://xxxxx.com/upload',
    filePath: res.tempFilePath,
    name: 'files',
    header: {
      "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
    },
    formData: {},
    success: function (res) {

      let img = "list[" + index + "].fileList"
      var fileList = that.data.list[index].fileList;
      fileList.push({ url: res.tempFilePath})

      let imgs = that.data.list[index].imgData;
      imgs.push(JSON.parse(res.data).data[0])
      let image = "list[" + index + "].imgData"

      that.setData({
        [image]: image,
        [img]: fileList
      })

    },
    fail: function (res) {}
  })
},

第五步:删除图片

deleteImg (e) {
  let that = this
  let index  = e.currentTarget.dataset.index 
  let idx = e.currentTarget.dataset.k

  let fileList = this.data.list[index].fileList
  fileList.splice(idx, 1)
  let file = "list[" + index + "].fileList"

  let imgs = this.data.list[index].imgData
  imgs.splice(idx, 1)
  let img = "list[" + index + "].imgData"

  this.setData({
    [file]:fileList,
    [img]: fileLists,
  })
},

图片上传前验证

一定要记得加 use-before-read 哦。

<van-uploader 
    max-count="1" 
    file-list="{{ fileList }}" 
    use-before-read 
    bind:before-read="beforeRead" 
    multiple="{{false}}" 
    upload-text='上传图片' 
/>

判断大小不能超过10M ,通过file.size判断。

图片格式必须是.png和.jpg,通过file.url的后缀名判断。

beforeRead(event) {
  
  const { file, callback } = event.detail;
  console.log(file)

  if (file.size > 10 * 1024 * 1024) {
    wx.showToast({
      title: '文件大小不能超过 10M!',
      icon: 'none'
    })
    callback(false);
  }

  let name = file.url.substring(file.url.lastIndexOf("."));

  if (name != '.png' && name != '.jpg') {
    wx.showToast({
      title: '图片必须是 .png 或 .jpg!',
      icon: 'none'
    })
    callback(false);
  }

  callback(true)
},

file的值


本文转载自: https://blog.csdn.net/wuli_youhouli/article/details/127787802
版权归原作者 宾果的救星 所有, 如有侵权,请联系我们删除。

“【Vant Weapp】van-uploader 文件上传”的评论:

还没有评论