改造vant-weapp的uploader组件以支持视频和图片同时预览

2,807 阅读3分钟
因为公司想做一款类商城小程序,涉及到上传图片和视频,之前有看到vant-weapp里面有一个uploader组件可以使用;所以直接拿过来用了;但是在看文档的过程中发现和实际需求不一致;

本着做之前先看有没有前人栽树的原则,发现这个需求网上没有搜到;

既然没有搜到,那自个也不想重新写一个组件,所以想着直接改一下现成的组件得了;

我们的需求是最多且只能有一个视频,如果有视频则最多只能上传八张;如果没有视频则最多上传九张;而且视频使用保持在第一个的位置;

那就先找到该组件的.wxml文件,


没什么复杂的,

那我们开始改造一下;首先把我们剥离出需要的组件,当然是直接copy了,为了样式统一呢,

    <view        wx:if='{{ video.url || video.path }}'  //在这里我新增一个属性,如果该属性有值则显示,也就是视频        class="van-uploader__preview"        data-index="{{ 0 }}"    //因为只会排在第一个,所以固定值index=0        bindtap="onClickVideo"   //点击事件需求修改为自己的逻辑
        data-url='{{video.url}}'  //视频传过去新页面播放        style="width: {{ utils.addUnit(previewSize) }}; height: {{ utils.addUnit(previewSize) }};"      >        <image        mode="aspectFit"   //直接使用小程序image组件的 mode="aspectFit"         src="{{ video.url || video.path }}"    //视频的封面地址        alt="{{ video.name || ('视频' + index) }}"        class="van-uploader__preview-image"        style="background-color:#000; opacity:.95; width: {{ utils.addUnit(previewSize) }}; height: {{ utils.addUnit(previewSize) }};"        data-index="{{ 0 }}"   //默认下坐标0      />
      <van-icon name="play" color='#fff' size='20px' class="videoPlay" />   <!--覆盖封面图的播放的按钮-->      <van-icon        wx:if="{{ deletable }}"        name="clear"        class="van-uploader__preview-delete"        data-index="{{ 0 }}"   //默认下坐标0        catch:tap="deleteItem"      />      </view>


新增之后的地方

.js文件里面需要新增一个video属性;我上传一个对象,


新增的方法,里面写自己的逻辑即可;我是跳转新页面直接播放


.js文件里还有几个注意的地方;

因为有视频的原因,导致下坐标都有可能+1;所以需要调整组件方法,像预览的时候坐标就需要-1处理



到此uploader修改完了,现在调整调用组件的页面;

该页面我有参考该大佬的文章 微信小程序 :使用vant实现上传图片功能

引入组件时我添加上了之前自定义属性的video


在上面我新增了上传之前的beforRead方法来验证

 beforeRead(event) {      console.log(event)      const { file, callback } = event.detail;      let videoNum = 0;      for (let i = 0; i < file.length; i++) {        let suffix = this.verifySuffix(file[i].tempFilePath || '');        //判断后缀        if (suffix == '.jpg' || suffix == '.jpeg' || suffix == '.png') {     //图片        } else if (suffix == '.mp4') {   //判断是否是视频          videoNum++        }      }      if (videoNum > 1) {     //大于两个首先排除        wx.showToast({          title: '最多只能有一个视频哦',          icon: 'none'        });        callback(false)      } else if (this.data.video.url && videoNum > 0) {    //大于一个的时候,如果已有视频也排除        wx.showToast({          title: '最多只能有一个视频哦',          icon: 'none'        });        callback(false)      } else {        callback(true);      }    }

还有一个注意点就是删除的时候,同样也是坐标系的问题需要注意

deleteImg(event) {        //删除图片 或视频      const delIndex = event.detail.index;      const { fileList } = this.data;      if(this.data.video.url &&  delIndex==0){    //先判断是否有视频,如果有的话则不适用直接删        //delIndex=0代表需要删视频;        this.setData({          video:{url:"",postImg:""}        })      }else if(this.data.video.url){        fileList.splice(delIndex-1, 1);   //有视频的需要-1删        this.setData({fileList})      }else{        fileList.splice(delIndex, 1);        this.setData({fileList})      }    }

上传的时候;就是判断一下后缀,如果是视频就赋值上去,图片就按照之前的逻辑走即可;

菜鸡记录以便日后参考;写的不够好请见谅