用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 正则替换 replace(regExp, function)用法
May 22 Javascript
收集的10个免费的jQuery相册
Feb 26 Javascript
Windows8下搭建Node.js开发环境教程
Sep 03 Javascript
javascript中indexOf技术详解
May 07 Javascript
浅谈javascript中的constructor
Jun 08 Javascript
JavaScript编程中实现对象封装特性的实例讲解
Jun 24 Javascript
jquery判断iPhone、Android设备类型
Sep 14 Javascript
jQuery实现文字自动横移
Jan 08 Javascript
完美的js图片轮换效果
Feb 05 Javascript
js时间戳和c#时间戳互转方法(推荐)
Feb 15 Javascript
node.js中module模块的功能理解与用法实例分析
Feb 14 Javascript
实例分析javascript中的异步
Jun 02 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&amp;java(二)
2006/10/09 PHP
ecshop 订单确认中显示省市地址信息的方法
2010/03/15 PHP
介绍一些PHP判断变量的函数
2012/04/24 PHP
php单文件版在线代码编辑器
2015/03/12 PHP
php实现可运算的验证码
2015/11/10 PHP
js中top/parent/frame概述及案例应用
2013/02/06 Javascript
js获取GridView中行数据的两种方法 分享
2013/07/13 Javascript
jquery 循环显示div的示例代码
2013/10/18 Javascript
js判断ie版本号的简单实现代码
2014/03/05 Javascript
基于NodeJS的前后端分离的思考与实践(一)全栈式开发
2014/09/26 NodeJs
NodeJS学习笔记之Http模块
2015/01/13 NodeJs
浅析Node.js 中 Stream API 的使用
2015/10/23 Javascript
JavaScript的设计模式经典之代理模式
2016/02/24 Javascript
对比分析Django的Q查询及AngularJS的Datatables分页插件
2017/02/07 Javascript
angular+bootstrap的双向数据绑定实例
2017/03/03 Javascript
解决Vue2.0自带浏览器里无法打开的原因(兼容处理)
2017/07/28 Javascript
Nodejs+express+ejs简单使用实例代码
2017/09/18 NodeJs
JS简单判断是否在微信浏览器打开的方法示例
2019/01/08 Javascript
vue中$nextTick的用法讲解
2019/01/17 Javascript
vue配置多代理服务接口地址操作
2020/09/08 Javascript
vue-cli3 热更新配置操作
2020/09/18 Javascript
Python通过正则表达式选取callback的方法
2015/07/18 Python
python实现随机梯度下降法
2020/03/24 Python
在IPython中进行Python程序执行时间的测量方法
2018/11/01 Python
python 统计文件中的字符串数目示例
2019/12/24 Python
python简单利用字典破解zip文件口令
2020/09/07 Python
Python中random模块常用方法的使用教程
2020/10/04 Python
5款实用的python 工具推荐
2020/10/13 Python
Pat McGrath Labs官网:世界上最有影响力的化妆师推出的彩妆品牌
2018/01/07 全球购物
匡威西班牙官网:Converse西班牙
2019/10/01 全球购物
T3官网:头发造型工具
2019/12/26 全球购物
建筑横幅标语
2014/10/09 职场文书
2014年医生工作总结
2014/11/21 职场文书
学校运动会开幕词
2016/03/03 职场文书
Python多线程 Queue 模块常见用法
2021/07/04 Python
Ubuntu安装Mysql+启用远程连接的完整过程
2022/06/21 Servers