用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动画2.元素坐标动画效果(创建一个图片走廊)
Aug 24 Javascript
js实现倒计时时钟的示例代码
Dec 17 Javascript
jquery实现当滑动到一定位置时固定效果
Jun 17 Javascript
解决JS请求服务器gbk文件乱码的问题
Oct 16 Javascript
分分钟玩转Vue.js组件(二)
Mar 01 Javascript
深究AngularJS中$sce的使用
Jun 12 Javascript
vue按需加载组件webpack require.ensure的方法
Dec 13 Javascript
vue-cli 目录结构详细讲解总结
Jan 15 Javascript
vue.js表单验证插件(vee-validate)的使用教程详解
May 23 Javascript
echarts实现折线图的拖拽效果
Dec 19 Javascript
JS实现图片幻灯片效果代码实例
May 21 Javascript
深入分析jQuery.one() 函数
Jun 03 jQuery
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学习之 认清变量的作用范围
2010/01/26 PHP
PHP 小心urldecode引发的SQL注入漏洞
2011/10/27 PHP
php.ini save_handler 修改不生效的解决办法
2014/07/22 PHP
php版微信自动登录并获取昵称的方法
2016/09/23 PHP
关于 Laravel Redis 多个进程同时取队列问题详解
2017/12/25 PHP
PHP 进程池与轮询调度算法实现多任务的示例代码
2019/11/26 PHP
JavaScript 放大镜 移动镜片效果代码
2011/05/09 Javascript
检测jQuery.js是否已加载的判断代码
2011/05/20 Javascript
Javascript对象中关于setTimeout和setInterval的this介绍
2012/07/21 Javascript
js限制textarea每行输入字符串长度的代码
2012/10/31 Javascript
Ionic实现仿通讯录点击滑动及$ionicscrolldelegate使用分析
2016/01/18 Javascript
探究Vue.js 2.0新增的虚拟DOM
2016/10/20 Javascript
原生JS版和jquery版实现checkbox的全选/全不选/点选/行内点选(Mr.Think)
2016/10/29 Javascript
谈谈第三方App接入微信登录 解读
2016/12/27 Javascript
Input文本框随着输入内容多少自动延伸的实现
2017/02/15 Javascript
jQuery EasyUI tree增加搜索功能的实现方法
2017/04/27 jQuery
如何编写一个d.ts文件的步骤详解
2018/04/13 Javascript
vue中typescript装饰器的使用方法超实用教程
2019/06/17 Javascript
JS函数进阶之prototy用法实例分析
2020/01/15 Javascript
Jquery+javascript实现支付网页数字键盘
2020/12/21 jQuery
[34:27]DOTA2上海特级锦标赛B组败者赛 VG VS Spirit第一局
2016/02/26 DOTA
python 简单的多线程链接实现代码
2016/08/28 Python
Python使用sort和class实现的多级排序功能示例
2018/08/15 Python
python框架中flask知识点总结
2018/08/17 Python
详解Django-channels 实现WebSocket实例
2019/08/22 Python
CSS3图片旋转特效(360/60/-360度)
2013/10/10 HTML / CSS
HTML5印章绘制电子签章图片(中文英文椭圆章、中文英文椭圆印章)
2019/06/03 HTML / CSS
英国床和浴室商场:Bed & Bath Emporium
2018/05/20 全球购物
英国Flybe航空官网:欧洲最大的独立支线廉价航空公司
2019/07/15 全球购物
数据库测试通常都包括哪些方面
2015/11/30 面试题
中医药大学市场营销专业自荐信
2013/09/29 职场文书
健康状况证明书
2014/11/26 职场文书
公司欠款证明
2015/06/24 职场文书
大学毕业典礼致辞
2015/07/29 职场文书
优秀共产党员主要事迹材料
2015/11/05 职场文书
Spring Boot 启动、停止、重启、状态脚本
2021/06/26 Java/Android