我的编程空间,编程开发者的网络收藏夹
学习永远不晚

解读vant的Uploader上传问题

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

解读vant的Uploader上传问题

vant的Uploader上传

vant的uploader组件的交互是点击上传之后才会触发一系列回调函数,如果想要实现点击uploader的时候先出现弹框提示,选择了确定之后才进行文件上传这该怎么做到呢?

大致是,给uploader组件外面包裹一层元素,然后给组件设为禁用模式,当外层的元素状态改变时,就改变组件的disabled值,再使用vant提供的chooseFile通过 ref 可以获取到 Uploader 实例并调用实例的方法重新调起文件选择。

主要的步骤如下

首先,我们可以在uploader组件外面包裹一层div

    <span
      @click="handleClick"
      v-if="isconfirm"
      class="message"
    ></span>
    <van-uploader
      v-model="fileList"
      :after-read="afterRead"
      :disabled="isconfirm"
      ref="uploadImg"
    />

然后在data以及methods中进行定义

data() {
    return {
      fileList: [],
      isconfirm: true
 };
  methods: {
    handleClick() {
      this.$dialog
        .confirm({
          message: "test,test,test"
        })
        .then(() => {
          this.isconfirm = false;
          this.$refs.uploadImg.chooseFile();
        })
        .catch(() => {
          this.isconfirm = true;
        });
    },
  }

看到这里要注意chooseFile这个方法支持的版本是v2.5.6以上的,如果出现了没有效果的话,先检查一下自己安装的版本是否是符合要求的。

检查之后,版本也符合要求,但是this.$refs.uploadImg.chooseFile()就是没有效果,这是怎么一回事呢?

原来跟浏览器执行机制event loop有关,每当执行到choosefile的时候,组件仍为禁用模式,无法调起,其实isconfirm状态还没有进行改变,所以调起文件选择看不见效果,可以使用一个setTimeout或者是vue中的this.$nextTick()进行解决。

setTimeout(() => {
    this.$refs.uploadImg.chooseFile();
 }, 0);
 
this.$nextTick(() => {
     this.$refs.uploadImg.chooseFile();
});

vant文件上传Uploader图片压缩

为什么要对图片进行压缩?

随着科技的发展,手机像素越来越好,拍摄的图片也越来越清晰。图片越清晰,体积也就越大。当移动端上传大图时就会发生卡顿,请求超时的情况。

当图片过大时,图片预览也会非常慢,所以需要在图片上传时对图片进行压缩。

vant中文件上传组件Uploader并不支持图片压缩,因为业务场景中有多个地方需要上传图片时对图片进行压缩,所以我基于Uploader封装了一个新的组件。

Uploader组件封装

此组件封装 基于vant文件上传Uploader

API

属性名属性说明默认值

quality

压缩质量【0-1】0.5

compressSwitch

是否开启压缩false

threshold

达到此大小开始压缩【500k】500

Vant 文件上传Uploader属性请参照 vant官网

模板部分

<template>
    <van-uploader :fileList="$attrs.value" :before-read="beforeReadFn" v-bind="$attrs" v-on="$listeners"/>
</template>

Javascript部分

export default {
  name: 'van-small-upload',
  props: {
    quality:{
      type:Number,
      default:0.1
    },
    compressSwitch:{
      type:Boolean,
      default:false
    },
    threshold:{
      type:Number,
      default:500
    },
    beforeRead:{
      type: Function,
      default:()=>true
    }
  },
  data() {
    return {
 
    }
  },
  methods: {
    // 处理图片
    imgPreview(file,index) {
      console.log('处理图片Fn...');
      let self = this
      // 看支持不支持FileReader
      if (!file || !window.FileReader) return;
      const size = file.size/1024
      console.log(`图片大小 ===> ${file.size/1024}k`);
      console.log('图片压缩:',this.compressSwitch?'开':'关');
      console.log('图片压缩阈值:',this.threshold+'k');
      console.log('图片压缩降帧值:',this.quality);
      if (/^image/.test(file.type) && size >= this.threshold && this.compressSwitch) {
        // 创建一个reader
        let reader = new FileReader()
        // 将图片2将转成 base64 格式
        reader.readAsDataURL(file)
        // 读取成功后的回调
        reader.onloadend = function() {
          let result = this.result
          let img = new Image()
          img.class="lazy" data-src = result
          img.onload = function() {
            // 压缩
            let data = self.compress(img,file.name,file.type)
            console.log(`压缩后 ===>${data.fileData.size/1024}k`);
            self.$attrs.value[index].content = data.base64Data
            self.$attrs.value[index].file = data.fileData
          }
        }
      }
    },
    // 压缩图片
    compress(img, name, type) {
      let canvas = document.createElement('canvas')
      let ctx = canvas.getContext('2d')
      //瓦片canvas
      let tCanvas = document.createElement('canvas')
      let tctx = tCanvas.getContext('2d')
      // let initSize = img.class="lazy" data-src.length;
      let width = img.width
      let height = img.height
      //如果图片大于四百万像素,计算压缩比并将大小压至400万以下
      let ratio
      if ((ratio = (width * height) / 4000000) > 1) {
        // console.log("大于400万像素");
        ratio = Math.sqrt(ratio)
        width /= ratio
        height /= ratio
      } else {
        ratio = 1
      }
      canvas.width = width
      canvas.height = height
      //    铺底色
      ctx.fillStyle = '#fff'
      ctx.fillRect(0, 0, canvas.width, canvas.height)
      //如果图片像素大于100万则使用瓦片绘制
      let count
      if ((count = (width * height) / 1000000) > 1) {
        // console.log("超过100W像素");
        count = ~~(Math.sqrt(count) + 1) //计算要分成多少块瓦片
        //      计算每块瓦片的宽和高
        let nw = ~~(width / count)
        let nh = ~~(height / count)
        tCanvas.width = nw
        tCanvas.height = nh
        for (let i = 0; i < count; i++) {
          for (let j = 0; j < count; j++) {
            tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh)
            ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh)
          }
        }
      } else {
        ctx.drawImage(img, 0, 0, width, height)
      }
      //进行压缩 
      let ndata = canvas.toDataURL('image/jpeg', this.quality)
      tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
      return {base64Data:ndata,fileData:this.dataURLtoFile(ndata,name,type)}
    },
    //将base64转换为文件
    dataURLtoFile(dataurl,name,type) {
      name = name ? name : '图片'
      type = type ? type : 'jpg'
      var arr = dataurl.split(','),
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], name, {
        type: type
      })
    },
    beforeReadFn(file,detail){
      const {index} = detail
      this.imgPreview(file,index)
      return this.beforeRead(...arguments);
    }
  },
  mounted(){
    
  }
};

使用示例

<SmUpload v-model="fileList" :before-read="beforeRead" :compressSwitch="true" :quality="0.5"/>

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

解读vant的Uploader上传问题

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

解读vant的Uploader上传问题

这篇文章主要介绍了解读vant的Uploader上传问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-13

vant的Uploader 文件上传,图片数据回显问题

这篇文章主要介绍了vant的Uploader 文件上传,图片数据回显问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-13

使用vant-uploader上传照片无法删除的解决

这篇文章主要介绍了使用vant-uploader上传照片无法删除的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-13

ecshop商品批量上传乱码读CSV的方式问题

客户反映,ECShop后台用CSV批量上传商品数据包出现一堆乱码,字段完全对不上。分析了代码后发现,ECShop读CSV的方式弱爆了。在adminwww.cppcns.com/目录下找到good_batch.php这段代码 复制代码代码如下
2022-06-12

Vue props传入function时的this指向问题解读

这篇文章主要介绍了Vue props传入function时的this指向问题解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-01-28

Vant-list上拉加载及下拉刷新问题怎么解决

本篇内容介绍了“Vant-list上拉加载及下拉刷新问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Vant-list 上拉加载及
2023-06-30

Vue3+vant+ts上滑加载解决上滑调用多次数据的问题(推荐)

这篇文章主要介绍了Vue3+vant+ts上滑加载解决上滑调用多次数据的问题,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2022-12-28

微信多图上传解决android多图上传失败问题

微信提供了文件上传的方法wx.uploadFile来上传我们的图片wx.chooseImage({success: function(res) {var tempFilePaths = res.tempFilePathswx.uploadF
2022-06-06

php上传中文文件无法上传问题怎么解决

php上传中文文件无法上传的解决办法:1、通过“iconv("GBK", "UTF-8", $content);”方法将中文字符编码转换一下;2、将文件重命名即可。
2023-05-14

Android 解决WebView无法上传文件的问题

Android 解决WebView无法上传文件的问题Android原生的WebView并不支持上传文件,需要我们自己实现相应的方法。于是我把工作中的相关代码记录下来。下次直接拿来用就行了。一点一滴都是经验。 1。需要定义三个变量 priva
2023-05-30

vant-list上拉加载onload事件触发多次问题及解决

这篇文章主要介绍了vant-list上拉加载onload事件触发多次问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-01-17

怎么解决php上传文件出错问题

这篇文章将为大家详细讲解有关怎么解决php上传文件出错问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。php上传文件出错的解决办法:1、在php.ini配置文件中设置“post_max_size”的值;
2023-06-08

编程热搜

目录