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


Posted in Javascript onFebruary 12, 2019

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

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

效果展示

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

项目执行流程

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

  • 前端向后端请求用来上传图片至服务器的token
  • 后端为每张要上传的图片生成一个图片名,并用这个图片名生成token
  • 后端将图片名和token返回给前端
  • 前端拿到token以后,将图片上传至服务器
  • 上传成功以后,前端将图片名发给后端
  • 后端将图片名存入数据库

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

项目实现过程

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

//upload.vue
<el-upload
 :action= domain
 ref="upload"
 accept='image/jpeg,image/gif,image/png'
 :auto-upload="false"
 :http-request="upqiniu"
 :limit="limit"
 :multiple="multiple"
 list-type="picture-card"
 :before-upload="beforeUpload"
 :on-preview="handlePictureCardPreview"
 :on-change="handldChange"
 :on-remove="handleRemove">
 <i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
 <img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>

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)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
发布BlueShow v1.0 图片浏览器(类似lightbox)blueshow.js 打包下载
Jul 21 Javascript
JavaScript高级程序设计 阅读笔记(十七) js事件
Aug 14 Javascript
如何使用JS获取IE上传文件路径(IE7,8)
Jul 08 Javascript
JS替换字符串中字符即替换全部而不是第一个
Jun 04 Javascript
jQuery制作拼图小游戏
Jan 12 Javascript
在JavaScript中使用对数Math.log()方法的教程
Jun 15 Javascript
javascript实现树形菜单的方法
Jul 17 Javascript
关于backbone url请求中参数带有中文存入数据库是乱码的快速解决办法
Jun 13 Javascript
js实现显示手机号码效果
Mar 09 Javascript
JS 组件系列之Bootstrap Table 冻结列功能IE浏览器兼容性问题解决方案
Jun 30 Javascript
Nuxt页面级缓存的实现
Mar 09 Javascript
vue项目中使用vue-layer弹框插件的方法
Mar 11 Javascript
PostgreSQL Node.js实现函数计算方法示例
Feb 12 #Javascript
Vue 动态组件与 v-once 指令的实现
Feb 12 #Javascript
在微信小程序中保存网络图片
Feb 12 #Javascript
VUE中使用MUI方法
Feb 12 #Javascript
如何利用ES6进行Promise封装总结
Feb 11 #Javascript
在vue项目中引入vue-beauty操作方法
Feb 11 #Javascript
Vue表单控件绑定图文详解
Feb 11 #Javascript
You might like
PHP OPCode缓存 APC详细介绍
2010/10/12 PHP
用Php编写注册后Email激活验证的实例代码
2013/03/11 PHP
php+ajax登录跳转登录实现思路
2016/07/31 PHP
php json_encode与json_decode详解及实例
2016/12/13 PHP
phpStudy配置多站点多域名方法及遇到的403错误解决方法
2017/10/19 PHP
PHP实现的解汉诺塔问题算法示例
2018/08/06 PHP
Laravel框架源码解析之模型Model原理与用法解析
2020/05/14 PHP
如何利用PHP实现上传图片功能详解
2020/09/24 PHP
鼠标移动到一张图片时变为另一张图片
2006/12/05 Javascript
表单项的name命名为submit、reset引起的问题
2007/12/22 Javascript
Javascript 面向对象(二)封装代码
2012/05/23 Javascript
Jquery实现显示和隐藏的4种简单方式
2013/08/28 Javascript
js解决弹窗问题实现班级跳转DIV示例
2014/01/06 Javascript
使用js画图之圆、弧、扇形
2015/01/12 Javascript
使用JavaScript脚本判断页面是否在微信中被打开
2016/03/06 Javascript
jQuery中设置form表单中action值的实现方法
2016/05/25 Javascript
JS实现重新加载当前页面或者父页面的几种方法
2016/11/30 Javascript
angularJs 表格添加删除修改查询方法
2018/02/27 Javascript
jquery实现点击左右按钮切换图片
2021/01/27 jQuery
Python基于PyGraphics包实现图片截取功能的方法
2017/12/21 Python
Python实现通过继承覆盖方法示例
2018/07/02 Python
python中scikit-learn机器代码实例
2018/08/05 Python
解读python如何实现决策树算法
2018/10/11 Python
Python DataFrame一列拆成多列以及一行拆成多行
2019/08/06 Python
python tkinter组件使用详解
2019/09/16 Python
python多线程实现同时执行两个while循环的操作
2020/05/02 Python
顶丰TOPPIK台湾官网:增发纤维假发,告别秃发困扰
2018/06/13 全球购物
澳大利亚Rockwear官网:女子瑜伽、健身和运动服
2021/01/26 全球购物
销售会计工作职责
2013/12/02 职场文书
大课间活动制度
2014/01/18 职场文书
写自荐信的注意事项
2014/03/09 职场文书
2014企业领导班子四风对照检查材料思想汇报
2014/09/17 职场文书
法英专业大学生职业生涯规划范文:衡外情,量己力!
2014/09/23 职场文书
抢劫罪辩护词
2015/05/21 职场文书
Java 垃圾回收超详细讲解记忆集和卡表
2022/04/08 Java/Android
python 使用pandas读取csv文件的方法
2022/12/24 Python