H5移动端vue+vant实现图片单张/批量上传(超1M压缩处理)

这是一个很常见的需求,但是我在写代码的过程中发现一些坑,就想为大家(包括踩坑前的我)打开一扇大门,话不多说,上才艺。

html部分用到vant UI库的van-uploader

 <!-- 上传附件 -->
  <div class="uploadImg">
    <span class="isMust">*</span>
    <p class="uploadImg-title">4、附件上传(最多上传9张)</p>
    <van-uploader
      :after-read="onRead"
      :accept="'image/*'"
      v-model="fileList"
      multiple
      @delete="delImg"
      :max-count="9"
    />
  </div>

js的data部分:

  data() {
    return {
      fileList: [],
    };
  },

分两种情况:

1、单张图片上传,注意此时传过来的file是对象,以下就是针对对象的处理方法

 下面的代码可直接搬哈,只是把存图片地址的 fileList替换成自己的参数即可,具体就是先判断当前图片大小,如果>1M,就要压缩再上传:


    // 图片上传后
    onRead(file) {
      console.log("上传的file", file);
      // 大于1MB的jpeg和png图片都缩小像素上传
      file.status = "uploading";
      file.message = "上传中...";
      // 如果是单张图片,fille是对象,当上传图片大于1M时,压缩上传
      if (file.file) {
        if (
          /\/(?:jpeg|png)/i.test(file.file.type) &&
          file.file.size > 1000000
        ) {
          console.log("大于1Mb");
          // 创建Canvas对象(画布)
          let canvas = document.createElement("canvas");
          // 获取对应的CanvasRenderingContext2D对象(画笔)
          let context = canvas.getContext("2d");
          // 创建新的图片对象
          let img = new Image();
          // 指定图片的DataURL(图片的base64编码数据)
          img.src = file.content;
          // 监听浏览器加载图片完成,然后进行进行绘制
          img.onload = () => {
            var newWidth = img.width * 0.7; //压缩后图片的宽度
            var newHeight = img.height * 0.7; //压缩后图片的高度
            // 指定canvas画布大小,该大小为最后生成图片的大小
            canvas.width = newWidth;
            canvas.height = newHeight;
            /* drawImage画布绘制的方法。(0,0)表示以Canvas画布左上角为起点,400,300是将图片按给定的像素进行缩小。
                        如果不指定缩小的像素图片将以图片原始大小进行绘制,图片像素如果大于画布将会从左上角开始按画布大小部分绘制图片,最后的图片就是张局部图。*/
            context.drawImage(img, 0, 0, newWidth, newHeight);
            // 将绘制完成的图片重新转化为base64编码,file.file.type为图片类型,0.92为默认压缩质量
            file.content = canvas.toDataURL(file.file.type, 0.7);
            let data = {
              dirtype: "hlfw",
              message: file.content,
            };
            // 以下是请求
            // this.$post("/uploadImg", data)
            //   .then((res) => {
            //     if (res.result == "success") {
            //       file.uploadUrl = res.url;
            //       this.$toast(res.info);
            //       file.status = "";
            //       file.message = "";
            //     } else {
            //       this.$toast(res.info);
            //       file.status = "failed";
            //       file.message = "上传失败";
            //       if (!this.fileList[this.fileList.length - 1].uploadUrl) {
            //         this.fileList.splice(this.fileList.length - 1, 1);
            //       }
            //     }
            //   })
            //   .catch((err) => {
            //     console.log(err);
            //     this.$toast("上传超时 请重试");
            //     file.status = "failed";
            //     file.message = "上传失败";
            //     if (!this.fileList[this.fileList.length - 1].uploadUrl) {
            //       this.fileList.splice(this.fileList.length - 1, 1);
            //     }
            //   });
          };
        } else {
          let data = {
            dirtype: "hlfw",
            message: file.content,//这里可以这样传message  也可以直接传this.fileList.content(具体参数根据后端需求来写)
          };
          console.log("jijik", data,this.fileList);
          // this.$post("/uploadImg", data)
          //   .then((res) => {
          //     console.log("从v", res);
          //     if (res.result == "success") {
          //       file.uploadUrl = res.url;
          //       file.status = "";
          //       file.message = "";
          //     } else {
          //       this.$toast(res.info);
          //       file.status = "failed";
          //       file.message = "上传失败";
          //       if (!this.fileList[this.fileList.length - 1].uploadUrl) {
          //         this.fileList.splice(this.fileList.length - 1, 1);
          //       }
          //     }
            // })
            // .catch((err) => {
            //   console.log(err);
            //   console.log(this.fileList);
            //   file.status = "failed";
            //   file.message = "上传失败";
            //   this.$toast("上传超时 请重试");

            //   if (!this.fileList[this.fileList.length - 1].uploadUrl) {
            //     this.fileList.splice(this.fileList.length - 1, 1);
            //   }
            // });
        }
      }else(){
        // 这里是多条上传处理方式,根据自己需求搬
      },

以上就是单条上传,接下来说说批量上传,以下方法适用于,后端要求接收参数为对象(数组就不要for循环上传了)这里就是上面else里面的内容拉,我拆分来写,各位各取所需

 // 如果是批量,file就是数组
      else {
        for (let i = 0; i < file.length; i++) {
          if (
            /\/(?:jpeg|png)/i.test(file[i].file.type) &&
            file[i].file.size > 1000000
          ) {
            console.log("大于1Mb");
            // 创建Canvas对象(画布)
            let canvas = document.createElement("canvas");
            // 获取对应的CanvasRenderingContext2D对象(画笔)
            let context = canvas.getContext("2d");
            // 创建新的图片对象
            let img = new Image();
            // 指定图片的DataURL(图片的base64编码数据)
            img.src = file[i].content;
            // 监听浏览器加载图片完成,然后进行进行绘制
            img.onload = () => {
              var newWidth = img.width * 0.7; //压缩后图片的宽度
              var newHeight = img.height * 0.7; //压缩后图片的高度
              // 指定canvas画布大小,该大小为最后生成图片的大小
              canvas.width = newWidth;
              canvas.height = newHeight;
              /* drawImage画布绘制的方法。(0,0)表示以Canvas画布左上角为起点,400,300是将图片按给定的像素进行缩小。
                        如果不指定缩小的像素图片将以图片原始大小进行绘制,图片像素如果大于画布将会从左上角开始按画布大小部分绘制图片,最后的图片就是张局部图。*/
              context.drawImage(img, 0, 0, newWidth, newHeight);
              // 将绘制完成的图片重新转化为base64编码,file.file.type为图片类型,0.92为默认压缩质量
              file[i].content = canvas.toDataURL(file[i].file.type, 0.7);
              let data = {
                dirtype: "hlfw",
                message: file[i].content,
              };
              // this.$post("/uploadImg", data)
              //   .then((res) => {
              //     if (res.result == "success") {
              //       file.uploadUrl = res.url;
              //       this.$toast(res.info);
              //       file.status = "";
              //       file.message = "";
              //     } else {
              //       this.$toast(res.info);
              //       file.status = "failed";
              //       file.message = "上传失败";
              //       if (!this.fileList[this.fileList.length - 1].uploadUrl) {
              //         this.fileList.splice(this.fileList.length - 1, 1);
              //       }
              //     }
              //   })
              //   .catch((err) => {
              //     console.log(err);
              //     this.$toast("上传超时 请重试");
              //     file.status = "failed";
              //     file.message = "上传失败";
              //     if (!this.fileList[this.fileList.length - 1].uploadUrl) {
              //       this.fileList.splice(this.fileList.length - 1, 1);
              //     }
              //   });
            };
          } else {
            let data = {
              dirtype: "hlfw",
              message: this.fileList[i].content,
            };
            console.log("上传参数", data,'图片参数',this.fileList[i]);
            this.$post("/uploadImg", data)
              .then((res) => {
                console.log("从v", res);
                if (res.result == "success") {
                  file[i].uploadUrl = res.url;
                  file[i].status = "";
                  file[i].message = "";
                } else {
                  this.$toast(res.info);
                  file[i].status = "failed";
                  file[i].message = "上传失败";
                  if (!this.fileList[this.fileList.length - 1].uploadUrl) {
                    this.fileList.splice(this.fileList.length - 1, 1);
                  }
                }
              })
              .catch((err) => {
                console.log(err);
                console.log(this.fileList);
                file[i].status = "failed";
                [i].message = "上传失败";
                this.$toast("上传超时 请重试");

                if (!this.fileList[this.fileList.length - 1].uploadUrl) {
                  this.fileList.splice(this.fileList.length - 1, 1);
                }
              });
          }
        }
      }

其实呢,跟单张大同小异,只是我们这里的file接收到的是个数组,所以采用for轮询发请求上传的方式(再说一次:这是后端不接收数组的方式哈,如果你打得赢他,让他接收数组,方便一点)

至此完结,早日暴富,脱离苦海

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
移动端Vue Vant的Uploader组件可以很方便地实现上传压缩和旋转图片功能。首先,我们需要在Vue项目中引入Vue Vant库,并在需要使用Uploader的组件中注册该组件。 在页面中使用Uploader组件时,我们可以设置相关的属性来实现功能需求。首先是上传图片功能,可以通过设置`action`属性来指定图片上传的后端接口地址。上传成功后,可以通过监听`@success`事件来处理上传成功的逻辑,例如显示上传成功的提示信息或者将上传成功的图片URL保存到数据库等。 对于压缩图片的功能,我们可以使用该组件提供的`beforeRead`方法来获取用户要上传图片文件对象。然后,利用`HTMLCanvasElement`的`toBlob`方法对图片进行压缩,并将压缩后的图片对象传给Uploader组件进行上传。在压缩图片时,可以设置压缩的尺寸或者压缩的质量、压缩比等参数,以控制压缩后的图片大小适应实际需求。 要实现图片旋转的功能,我们可以利用`EXIF.js`库来读取图片的EXIF信息,获取图片的拍摄方向。然后,根据拍摄方向来确定图片需要旋转的角度,再借助`canvas`的`rotate`方法对图片进行旋转。旋转后的图片可以在`@success`事件触发后重新渲染到页面上,或者直接发送到后端进行保存。 总结来说,移动端Vue Vant的Uploader组件通过设置相关属性和监听事件,配合压缩工具和EXIF库,可以非常方便地实现图片上传压缩和旋转功能,满足移动端图片处理的需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值