Vant上传多个图片或视频,更改视频预览图

需求
  • vant上传多个视频或图片
  • 图片和视频都有预览图
最终成果

请添加图片描述

过程
  • 最开始是准备通过自定义预览样式,通过 preview-cover 插槽可以自定义覆盖在预览区域上方的内容。但问题是会修改每一个上传的图片和视频,都添加上播放视频的图片,不能实现直接预览图片的效果
  • 最终采用自定义单个图片预览
            <van-uploader
              accept="*"
              v-model="imgList"
              :after-read="afterRead"
              :before-read="beforeRead"
              preview-size='25vw'
              @click-preview="handleclicksc"
              :before-delete="afterDelete"
              :preview-full-image="false"
              :disabled="isUploading?true:false"
              />

<!--点击图片或视频出现放大图片或播放视频的弹窗-->
    <van-overlay :show="show" @click="show = false">
      <div class="wrapper" >
        <div class="img-block">
          <img v-if="urlType==='image'"   :src="url">
          <video autoplay class="video" v-if="urlType==='video'" :src="url" controls></video>
        </div>
<!--给视频添加关闭图标-->
          <img v-if="urlType==='video'"
            @click="show=false"
            class="video-delete"
            src="./close.png"
          />
        </div>
    </van-overlay>
data(){
    return {
        isUploading:false,
        allInfoList:[],
        url:'',  //弹窗展示的图片/视频路径
        urlType:'',  //弹窗展示的类型
    }
 },
  watch: {
  //监听allInfoList,根据allInfoList动态地修改文件列表
    'allInfoList' () {
      this.imgList = []
      for (let item of this.allInfoList) {
        let data = {
          type: item.type,
          name: item.originalName,
          url: item.type === 'video' ? 'https://replacement.png' : 'https://' + item.fileUri
        }
        this.imgList.push(data)
      }
    }
  },
methods:{
//限制上传的内容为视频或图片
    beforeRead (file) {
      if (!file.type.startsWith('image') && !file.type.startsWith('video')) {
        this.$toast('请上传图片或视频')
        return false
      }
      return true
    },

    afterRead (file) {
      file.status = 'uploading'
      file.message = '上传中...'
      //添加上传状态,避免用户在上传未完成时点击提交按钮
      this.isUploading = true
      fileApi
        .uploadFile(file.file)
        .then(res => {
          if (res.data.status === 'success') {
            let fileDTO = response.data.fileDTO
            //为返回的数据添加文件类型,后面依据此来判断
            if (file.file.type.startsWith('video')) {
              fileDTO.type = 'video'
            }
            if (file.file.type.startsWith('image')) {
              fileDTO.type = 'image'
            }
            //将返回的所有数据都保存起来(文件地址,文件名等)
            this.allInfoList.push(fileDTO)
          } else {
          //上传失败要清空数组,不然失败的文件依旧会展示
            this.handleDelete(file.file.name)
          }
          file.status = ''
          file.message = ''
          this.isUploading = false
        })
        .catch((error) => {
          console.log(error)
          this.handleDelete(file.file.name)
          file.status = ''
          file.message = ''
          this.isUploading = false
        })
    },
    //根据文件名来查找到文件列表中要删除的文件
    handleDelete (name) {
      this.imgList.forEach((item, index) => {
        if (item.file.name === name) {
          this.imgList.splice(index, 1)
        }
      })
    },
    //手动点击删除,修改包含所有信息的文件列表,通过watch根据该列表动态修改图片文件列表
    afterDelete (file) {
      let name = file.name
      this.allInfoList.forEach((item, index) => {
        if (item.originalName === name) {
          this.allInfoList.splice(index, 1)
        }
      })
      return true
    },
   }
   //取消掉组件自带的点击预览功能,自己添加(系统自带预览点击视频时会先视频的播放图片)
   handleclicksc (file) {
      let name = file.name
      for (let item of this.allInfoList) {
        if (item.type === 'video' && item.originalName === name) {
          this.url = this.getUrl(item.fileUri)
          this.urlType = 'video'
          this.show = true
        }
        if (item.type === 'image' && item.originalName === name) {
          this.url = this.getUrl(item.fileUri)
          this.urlType = 'image'
          this.show = true
        }
      }
    },
  .wrapper {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
  }
  .img-block {
    position: relative;
    img{
      z-index: 99;
      max-width: 100%;
      height: auto;
      object-fit: cover;
    }
    video{
      width: 100%;
      max-height: 100vh;
    }
  }
  .video-delete{
    width: 45px;
    position: absolute;
    top: 60px;
    left: calc(100vw - 60px);
  }
  • 1
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
vant是一个基于Vue.js的移动端UI组件库,它提供了一些方便易用的组件,包括图片上传组件。要实现多图片上传,你可以使用vantUploader组件。首先,你需要在项目中引入vant组件库,并按照文档进行配置和安装。 然后,你可以在你的Vue组件中使用Uploader组件,并设置多文件上传的属性:multiple为true。在上传成功后,你可以通过处理返回的数据来获取上传图片地址。 以下是一个使用vant实现多图片上传的示例代码: ```vue <template> <van-uploader v-model="files" :multiple="true" :after-read="afterRead" /> </template> <script> export default { data() { return { files: [] }; }, methods: { afterRead(file) { // 处理上传成功后的文件信息 console.log(file); // 获取上传后的图片地址 console.log(file.url); } } }; </script> ``` 在上面的代码中,`files`数组用于存储上传的文件信息,`afterRead`方法会在上传成功后触发,你可以在这里进行处理。 需要注意的是,使用vantUploader组件进行多图片上传时,你可能还需要根据你的需求进行一些额外的配置,比如限制图片的数量、大小、格式等。你可以参考vant的文档或者具体的需求进行相应的配置和处理。 希望以上信息对你有所帮助!<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [vue vantUI实现文件(图片、文档、视频、音频)上传(多文件)](https://download.csdn.net/download/weixin_38657115/12934331)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [vue +vant 适合手机端上传图片图片 实现了上传、压缩、旋转图片](https://download.csdn.net/download/weixin_38592548/14878499)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值