用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 相关文章推荐
laytpl 精致巧妙的JavaScript模板引擎
Aug 29 Javascript
jQuery选择器全集详解
Nov 24 Javascript
jQuery自动完成插件completer附源码下载
Jan 04 Javascript
javascript实现可键盘控制的抽奖系统
Mar 10 Javascript
javascirpt实现2个iframe之间传值的方法
Jun 30 Javascript
JS表格组件BootstrapTable行内编辑解决方案x-editable
Sep 01 Javascript
原生js实现addclass,removeclass,toggleclasss实例
Nov 24 Javascript
jQuery实现简单弹窗遮罩效果
Feb 27 Javascript
加载 vue 远程代码的组件实例详解
Nov 20 Javascript
详解Angular6学习笔记之主从组件
Sep 05 Javascript
在layui中select更改后生效的方法
Sep 05 Javascript
JavaScript WeakMap使用详解
Feb 05 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
SONY SRF-40W电路分析
2021/03/02 无线电
解析Extjs与php数据交互(增删查改)
2013/06/25 PHP
php实现Session存储到Redis
2015/11/11 PHP
PHP flush 函数使用注意事项
2016/08/26 PHP
Ajax,UTF-8还是GB2312 eval 还是execScript
2008/11/13 Javascript
jquery日历控件实现方法分享
2014/03/07 Javascript
jQuery多个input求和的实现方法
2015/02/12 Javascript
jquery带动画效果幻灯片特效代码
2015/08/27 Javascript
使用vue.js制作分页组件
2016/06/27 Javascript
ui组件之input多选下拉实现方法(带有搜索功能)
2016/07/14 Javascript
JS实现输入框提示文字点击时消失效果
2016/07/19 Javascript
javascript特效实现——当前时间和倒计时效果的简单实例
2016/07/20 Javascript
NodeJS中的MongoDB快速入门详细教程
2016/11/11 NodeJs
JavaScript实现经典排序算法之选择排序
2016/12/28 Javascript
javaScript嗅探执行神器-sniffer.js
2017/02/14 Javascript
原生JS实现层叠轮播图
2017/05/17 Javascript
jQuery Position方法使用和兼容性
2017/08/23 jQuery
Nodejs把接收图片base64格式保存为文件存储到服务器上
2018/09/26 NodeJs
在vue中更换字体,本地存储字体非引用在线字体库的方法
2018/09/28 Javascript
微信小程序实现联动选择器
2019/02/15 Javascript
vue项目移动端实现ip输入框问题
2019/03/19 Javascript
详解Python3中的Sequence type的使用
2015/08/01 Python
基于Python Shell获取hostname和fqdn释疑
2016/01/25 Python
pygame实现简易飞机大战
2018/09/11 Python
numpy ndarray 按条件筛选数组,关联筛选的例子
2019/11/26 Python
表达自我的市场:Society6
2018/08/01 全球购物
VICHY薇姿俄罗斯官方网上商店:法国护肤品牌,火山温泉水
2019/11/22 全球购物
如何减少垃圾回收让内存更加有效使用
2013/10/18 面试题
毕业生求职找工作的自我评价范文
2013/11/27 职场文书
给老师的道歉信
2014/01/11 职场文书
初中同学聚会邀请函
2014/02/03 职场文书
家具公司总经理岗位职责
2014/07/08 职场文书
质量保证书格式模板
2015/02/27 职场文书
创业计划书之酒厂
2019/10/14 职场文书
分析Python感知线程状态的解决方案之Event与信号量
2021/06/16 Python
教你使用VS Code的MySQL扩展管理数据库的方法
2022/01/22 MySQL