用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 中的事件教程
Apr 05 Javascript
javascript下有关dom以及xml节点访问兼容问题
Nov 26 Javascript
JavaScript 验证浏览器是否支持javascript的方法小结
May 17 Javascript
表单JS弹出填写提示效果代码
Apr 16 Javascript
html5 canvas js(数字时钟)实例代码
Dec 23 Javascript
js 通过cookie实现刷新不变化树形菜单
Oct 30 Javascript
基于vue.js轮播组件vue-awesome-swiper实现轮播图
Mar 17 Javascript
javascript实现非常简单的小数取整功能示例
Jun 13 Javascript
微信小程序实现action-sheet弹出底部菜单功能【附源码下载】
Dec 09 Javascript
express默认日志组件morgan的方法
Apr 05 Javascript
JavaScript设计模式之观察者模式实例详解
Jan 16 Javascript
弱类型语言javascript中 a,b 的运算实例小结
Aug 07 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结合web uploader插件实现分片上传文件
2016/05/10 PHP
php实现的错误处理封装类实例
2017/06/20 PHP
ThinkPHP框架实现的邮箱激活功能示例
2018/06/15 PHP
php根据命令行参数生成配置文件详解
2019/03/15 PHP
前端开发必须知道的JS之原型和继承
2010/07/06 Javascript
JS判断客户端是手机还是PC的2个代码
2014/04/12 Javascript
简介JavaScript中的push()方法的使用
2015/06/09 Javascript
JavaScript定义全局对象的方法示例
2017/01/12 Javascript
jQuery实现字符串全部替换的方法【推荐】
2017/03/09 Javascript
详解利用 Express 托管静态文件的方法
2017/09/18 Javascript
Bootstrap Tooltip显示换行和左对齐的解决方案
2017/10/11 Javascript
JS逻辑运算符短路操作实例分析
2018/07/09 Javascript
Vue实现移动端左右滑动效果的方法
2018/11/27 Javascript
js作用域和作用域链及预解析
2019/04/11 Javascript
vue-cli3.X快速创建项目的方法步骤
2019/11/14 Javascript
用JS实现选项卡
2020/03/23 Javascript
Python装饰器decorator用法实例
2014/11/10 Python
Pandas库之DataFrame使用的学习笔记
2019/06/21 Python
Windows10下Tensorflow2.0 安装及环境配置教程(图文)
2019/11/21 Python
Python实现一个简单的递归下降分析器
2020/08/01 Python
Python list和str互转的实现示例
2020/11/16 Python
详解win10下pytorch-gpu安装以及CUDA详细安装过程
2021/01/28 Python
html5视频常用API接口的实战示例
2020/03/20 HTML / CSS
详解移动端h5页面根据屏幕适配的四种方案
2020/04/15 HTML / CSS
TripAdvisor印尼站:全球领先的旅游网站
2018/03/15 全球购物
亚洲独特体验旅游专家:eOasia
2018/08/15 全球购物
马来西亚在线购物:POPLOOK.com
2019/12/09 全球购物
万豪国际住宅与别墅集团:Homes & Villas by Marriott International
2020/10/08 全球购物
Java面试题:请问一下代码输出是什么
2015/05/27 面试题
C#如何判断当前用户是否输入某个域
2015/12/07 面试题
预备党员的自我评价
2014/03/12 职场文书
员工安全生产承诺书
2014/05/22 职场文书
2014财务人员自我评价范文
2014/09/21 职场文书
2014年售后服务工作总结
2014/11/18 职场文书
python中requests库+xpath+lxml简单使用
2021/04/29 Python
python单向链表实例详解
2022/05/25 Python