用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 相关文章推荐
javascript如何判断输入的url是否正确
Apr 11 Javascript
兼容主流浏览器的JS复制内容到剪贴板
Dec 12 Javascript
jQuery调用ajax请求的常见方法汇总
Mar 24 Javascript
javascript简单实现类似QQ头像弹出效果的方法
Aug 03 Javascript
javascript实现手机震动API代码
Aug 05 Javascript
SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的
Dec 10 Javascript
实例讲解javascript注册事件处理函数
Jan 09 Javascript
JavaScript jquery及AJAX小结
Jan 24 Javascript
Vuex和前端缓存的整合策略详解
May 09 Javascript
解决option标签selected=&quot;selected&quot;属性失效的问题
Nov 06 Javascript
JavaScript实现新年倒计时效果
Nov 17 Javascript
Vue+penlayers实现多边形绘制及展示
Dec 24 Vue.js
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下判断数组中是否存在相同的值array_unique
2008/03/25 PHP
一家之言的经验之谈php+mysql扎实个人基本功
2008/03/27 PHP
PHP has encountered an Access Violation at 7C94BD02解决方法
2009/08/24 PHP
基于HTTP长连接的&quot;服务器推&quot;技术的php 简易聊天室
2009/10/31 PHP
php建立Ftp连接的方法
2015/03/07 PHP
帝国cms目录结构分享
2015/07/06 PHP
如何写php守护进程(Daemon)
2015/12/30 PHP
js玩一玩WSH吧
2007/02/23 Javascript
jquery 简单图片导航插件jquery.imgNav.js
2010/03/17 Javascript
jquery实现对联广告的方法
2015/02/05 Javascript
提高jQuery性能优化的技巧
2015/08/03 Javascript
原生js实现日期计算器功能
2017/02/17 Javascript
JavaScript如何使用插值实现图像渐变
2020/06/28 Javascript
[02:28]DOTA2 2017国际邀请赛小组赛回顾
2017/08/09 DOTA
用python 实现在不确定行数情况下多行输入方法
2019/01/28 Python
利用python3 的pygame模块实现塔防游戏
2019/12/30 Python
PyCharm2019.3永久激活破解详细图文教程,亲测可用(不定期更新)
2020/10/29 Python
python更新数据库中某个字段的数据(方法详解)
2020/11/18 Python
使用CSS3实现多列布局与多背景的技巧
2016/02/29 HTML / CSS
Bergfreunde丹麦:登山装备网上零售商
2017/02/26 全球购物
瑜伽服装品牌:露露柠檬(lululemon athletica)
2017/06/04 全球购物
Pure Collection美国官网:来自英国羊绒专家的奢华羊绒
2017/11/19 全球购物
Araks官网:纽约内衣品牌
2020/10/15 全球购物
一套Java笔试题
2016/08/20 面试题
.NET面试题:什么是值类型和引用类型
2016/01/12 面试题
校园餐饮创业计划书
2014/01/10 职场文书
个人委托书格式
2014/04/04 职场文书
导游个人求职信
2014/04/25 职场文书
婚纱店策划方案
2014/05/22 职场文书
珍惜资源的建议书
2014/08/26 职场文书
农村优秀教师事迹材料
2014/08/27 职场文书
2015年感恩母亲节的演讲稿
2015/03/18 职场文书
Python中的min及返回最小值索引的操作
2021/05/10 Python
python 办公自动化——基于pyqt5和openpyxl统计符合要求的名单
2021/05/25 Python
Python爬虫基础之初次使用scrapy爬虫实例
2021/06/26 Python
Redis实现分布式锁的五种方法详解
2022/06/14 Redis