资讯专栏INFORMATION COLUMN

用element的upload组件实现多图片上传和压缩

zorro / 1360人阅读

摘要:我用做状态管理,七牛云做图床。关于该组件的其他用法可以在的官方文档查阅上传对图片进行压缩压缩图片的质量对图片进行压缩压缩图片实现起来比较简单。前端向后端请求上传。

我用vuex做状态管理,七牛云做图床。

项目地址:多图片上传组件

效果展示

项目执行流程

首先,让我们来分析一下实现多图片上传的流程:

前端向后端请求用来上传图片至服务器的token

后端为每张要上传的图片生成一个图片名,并用这个图片名生成token

后端将图片名和token返回给前端

前端拿到token以后,将图片上传至服务器

上传成功以后,前端将图片名发给后端

后端将图片名存入数据库

项目实现过程

1.我们要利用element-ui的Upload组件布置界面:

//upload.vue

  


  

domain 指的是我们的上传地址,upqiniu 是我们自定义的上传方法,beforeUpload 是图片上传前执行的方法。关于该组件的其他用法可以在element的官方文档查阅:Upload 上传

2.对图片进行压缩

// upload.vue
imgQuality: 0.5, //压缩图片的质量

dataURItoBlob(dataURI, type) {
  var binary = atob(dataURI.split(",")[1]);
  var array = [];
  for(var i = 0; i < binary.length; i++) {
    array.push(binary.charCodeAt(i));
  }
  return new Blob([new Uint8Array(array)], {type: type});
},

beforeUpload(param) {
  //对图片进行压缩
  const imgSize = param.size / 1024 / 1024
  if(imgSize > 1) {
    const _this = this
    return new Promise(resolve => {
      const reader = new FileReader()
      const image = new Image()
      image.onload = (imageEvent) => {
        const canvas = document.createElement("canvas");
        const context = canvas.getContext("2d");
        const width = image.width * _this.imgQuality
        const height = image.height * _this.imgQuality
        canvas.width = width;
        canvas.height = height;
        context.clearRect(0, 0, width, height);
        context.drawImage(image, 0, 0, width, height);
        const dataUrl = canvas.toDataURL(param.type);
        const blobData = _this.dataURItoBlob(dataUrl, param.type);
        resolve(blobData)
      }
      reader.onload = (e => { image.src = e.target.result; });
      reader.readAsDataURL(param);
    })
  }
}

压缩图片实现起来比较简单。就是在beforeUpload()方法里面return一个Promise,Promise里面我们把图片的长度和宽度按比例进行缩小,并把图片画到canvas上,然后把canvas转成一个blod对象。

3.前端向后端请求上传token。

//upload.vue
upqiniu(param) {
  let filetype = ""
  if (param.file.type === "image/png") {
    filetype = "png"
  } else {
    filetype = "jpg"
  }
  const formdata = {
    filetype: filetype,
    param: param
  }
  this.actionGetUploadToken(formdata)        
}

// vuex/action.js
actionGetUploadToken({commit}, obj) {
  const msg = {
    filetype: obj.filetype
  }
  usersApi.getImgUploadToken(msg).then((response) => {
    if(response.stateCode === 200) {
      commit("uploadImg", {"token": response.token, "key": response.key, "param": obj.param})
    } 
  }, (error) => {
    console.log(`获取图片上传凭证错误:${error}`)
    commit("uploadImgError")
  })
},

4.后端生成上传token,并发给前端,我用Python实现。

filetype = data.get("filetype")
# 构建鉴权对象
q = Auth(configs.get("qiniu").get("AK"), configs.get("qiniu").get("SK"))

# 生成图片名
salt = "".join(random.sample(string.ascii_letters + string.digits, 8))
key = salt + "_" + str(int(time.time())) + "." + filetype

# 生成上传 Token,可以指定过期时间等
token = q.upload_token(configs.get("qiniu").get("bucket_name"), key, 3600)
return Response({"stateCode": 200, "token": token, "key": key}, 200)

5.前端接收token,开始向服务器上传图片

// vuex/state.js
imgName: [], //图片名数组

// vuex/mutations.js
uploadImg(state, msg) {
  const config = {
    useCdnDomain: true,
    region: qiniu.region.z2
  }
  var putExtra = {
    fname: msg.param.file.name,
    params: {},
    mimeType: ["image/png", "image/jpeg", "image/gif"]
  };
  var observer = {
    next(res){

    },
    error(err){
      console.log(`图片上传错误信息:${err.message}`)
    }, 
    complete(res){
      console.log(`图片上传成功:${res.key}`)
      state.imgName.push(res.key)
    }
  }
  var observable = qiniu.upload(msg.param.file, msg.key, msg.token, putExtra, config)
  //上传开始
  var subscription = observable.subscribe(observer)
},

6.上传成功以后,将图片名存入数据库

// 用到upload.vue的界面
this.imgsList = this.imgName.map(key => `http://${this.qiniuaddr}/${key}`)
switch(this.imgsList.length) {
  case 4:
  this.img4 = this.imgsList[3]
  case 3:
  this.img3 = this.imgsList[2]
  case 2:
  this.img2 = this.imgsList[1]
  case 1:
  this.img1 = this.imgsList[0]
}
let obj = {
  goods_img1: this.img1,
  goods_img2:this.img2,
  goods_img3:this.img3,
  goods_img4:this.img4
}
//将信息发送给后端
this.actionPublish(obj)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/43172.html

相关文章

  • element 上传组件 el-upload 经验总结

    摘要:正文上传图片到七牛云这个需要前后端的配合才能实现,这里是官方的参考链接。参考链接组件的怎么获取进度值谷歌找到的其一谷歌找到的其二完 前言 最近在做后台管理项目,采用的 vue-element-admin ,上传图片是一个很常用的功能,也遇到了很多问题,刚好趁此机会做一些总结。 初步总结下会提到的问题,目录如下: el-upload 自定义上传方法 图片上传到七牛云 图片压缩后再上传(...

    Neilyo 评论0 收藏0
  • Element-ui实现合并上传(一次请求图片

    摘要:实现多图上传主要用到以下两个属性是自带多图上传的,但是细心的朋友可能发现默认多图的实现可能和我们预期有些出入,有截图可以看出,实质是进行多次请求在上传事件触发后,多图上传的默认实现调用了三次请求。 前言 工作中碰到需要多图上传,在使用element-ui解决过程中碰到一些问题,在这里分享给大家。 环境: Springboot+Vue+Element-ui 正文 这次上传使用的是Elem...

    loostudy 评论0 收藏0
  • 前端临床手札——文件上传

    摘要:文件上传基本是学习前端路上必定遇到的例子,然而网上能找到的都是单单满足上传这步的案例。但前提是需要约定传入值和返回类型。 文件上传基本是学习前端路上必定遇到的例子,然而网上能找到的都是单单满足上传这步的案例。大多文章之所以只说上传这步估计是简单易入门,但是实际工作时就会发现上传文件这个功能上是简单的,逻辑上却比较复杂。 先说一下需求和功能点: 需求:上传文件到服务器 功能:上传 单这么...

    SexySix 评论0 收藏0
  • 在Vue项目中使WebUploader实现文件上传

    摘要:简介是由团队开发的一个简单的以为主,为辅的现代文件上传组件。采用大文件分片并发上传,极大的提高了文件上传效率。另外分片传输能够更加实时的跟踪上传进度。选择文件的按钮。 简介:WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的...

    mindwind 评论0 收藏0
  • 在Vue项目中使WebUploader实现文件上传

    摘要:简介是由团队开发的一个简单的以为主,为辅的现代文件上传组件。采用大文件分片并发上传,极大的提高了文件上传效率。另外分片传输能够更加实时的跟踪上传进度。选择文件的按钮。 简介:WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的...

    endiat 评论0 收藏0

发表评论

0条评论

zorro

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<