用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 相关文章推荐
jQuery基于json与cookie实现购物车的方法
Apr 15 Javascript
Node.js 8 中的重要新特性
Jun 28 Javascript
nginx配置React静态页面的方法教程
Nov 03 Javascript
jquery实现楼层滚动效果
Jan 01 jQuery
旺旺在线客服代码 旺旺客服代码生成器
Jan 09 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
Sep 26 Javascript
浅谈HTTP 缓存的那些事儿
Oct 17 Javascript
Vue.js 事件修饰符的使用教程
Nov 01 Javascript
vue-cli3 项目从搭建优化到docker部署的方法
Jan 28 Javascript
vue请求本地自己编写的json文件的方法
Apr 25 Javascript
JS插入排序简单理解与实现方法分析
Nov 25 Javascript
微信公众号服务器验证Token步骤图解
Dec 30 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
浅谈ThinkPHP中initialize和construct的区别
2017/04/01 PHP
Jquery插件 easyUI属性汇总
2011/01/19 Javascript
jquery html动态生成select标签出问题的解决方法
2013/11/20 Javascript
获取select元素被选中的文本内容的js代码
2014/01/29 Javascript
node.js中的console.assert方法使用说明
2014/12/10 Javascript
Javascript URI 解析介绍
2015/03/15 Javascript
js使用DOM操作实现简单留言板的方法
2015/04/10 Javascript
jQuery弹簧插件编写基础之“又见弹窗”
2015/12/11 Javascript
基于jQuery实现返回顶部实例代码
2016/01/01 Javascript
学习AngularJs:Directive指令用法(完整版)
2016/04/26 Javascript
使用jQuery制作浮动工具栏的实例分享
2016/05/13 Javascript
JS代码实现百度地图 画圆 删除标注
2016/10/12 Javascript
浅析JavaScript的几种Math函数,random(),ceil(),round(),floor()
2016/12/22 Javascript
Bootstrap table右键功能实现方法
2017/02/20 Javascript
javascript中神奇的 Date对象小结
2017/10/12 Javascript
在vue.js中使用JSZip实现在前端解压文件的方法
2018/09/05 Javascript
JavaScript Array对象使用方法解析
2019/09/24 Javascript
js实现简单掷骰子效果
2019/10/24 Javascript
JS中作用域以及变量范围分析
2020/07/18 Javascript
[49:35]KG vs SECRET 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
python中的全局变量用法分析
2015/06/09 Python
python学生信息管理系统
2018/03/13 Python
Python3.6.2调用ffmpeg的方法
2019/01/10 Python
Python collections模块使用方法详解
2019/08/28 Python
运行python提示no module named sklearn的解决方法
2020/11/29 Python
M1芯片安装python3.9.1的实现
2021/02/02 Python
数百万免费的图形资源:Freepik
2020/09/21 全球购物
采购主管的岗位职责
2013/12/17 职场文书
人力资源部经理的岗位职责
2014/03/04 职场文书
素质教育标语
2014/06/27 职场文书
奉献家乡演讲稿
2014/09/16 职场文书
员工工作自我评价
2014/09/26 职场文书
新娘父亲婚礼致辞
2015/07/27 职场文书
网吧管理制度范本
2015/08/05 职场文书
财务人员廉洁自律心得体会
2016/01/13 职场文书
小学三年级语文教学反思
2016/03/03 职场文书