用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或asp实现的判断身份证号码是否正确两种验证方法
Nov 26 Javascript
javascript跑马灯悬停放大效果实现代码
Dec 12 Javascript
Extjs4 GridPanel的主要配置参数详细介绍
Apr 18 Javascript
jQuery实现简单的列表式导航菜单效果代码
Aug 31 Javascript
基于JavaScript实现百叶窗动画效果不只单纯flas可以实现
Feb 29 Javascript
分享JS数组求和与求最大值的方法
Aug 11 Javascript
jQuery+CSS3实现四种应用广泛的导航条制作实例详解
Sep 17 Javascript
js 轮播效果实例分享
Dec 28 Javascript
JS中的事件委托实例浅析
Mar 22 Javascript
Node.js 的 GC 机制详解
Jun 03 Javascript
vue-cli3 取消eslint校验代码的解决办法
Jan 16 Javascript
uniapp,微信小程序中使用 MQTT的问题
Jul 11 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中for循环语句的几种变型
2007/03/16 PHP
php mssql 数据库分页SQL语句
2008/12/16 PHP
windows环境下php配置memcache的具体操作步骤
2013/06/09 PHP
PHP Curl出现403错误的解决办法
2014/05/29 PHP
PHP获取文件夹内文件数的方法
2015/03/12 PHP
php判断目录存在的简单方法
2019/09/26 PHP
Javascript处理DOM元素事件实现代码
2012/05/23 Javascript
基于jquery的文本框与autocomplete结合使用(asp.net+json)
2012/05/30 Javascript
JS.findElementById()使用介绍
2013/09/21 Javascript
jQuery中获取checkbox选中项等操作及注意事项
2013/11/24 Javascript
jquery中的常见问题及快速解决方法小结
2016/06/14 Javascript
第六篇Bootstrap表格样式介绍
2016/06/21 Javascript
微信小程序 122100版本更新问题解决方案
2016/12/22 Javascript
详谈js使用in和hasOwnProperty获取对象属性的区别
2017/04/25 Javascript
Bootstrap Tree View简单而优雅的树结构组件实例解析
2017/06/15 Javascript
vue中过滤器filter的讲解
2019/01/21 Javascript
详谈Object.defineProperty 及实现数据双向绑定
2020/07/18 Javascript
js实现淘宝浏览商品放大镜功能
2020/10/28 Javascript
python实现基本进制转换的方法
2015/07/11 Python
python函数局部变量、全局变量、递归知识点总结
2019/11/15 Python
python 的topk算法实例
2020/04/02 Python
基于python检查矩阵计算结果
2020/05/21 Python
详解python 条件语句和while循环的实例代码
2020/12/28 Python
CSS3 中filter(滤镜)属性使用详解
2020/04/07 HTML / CSS
HTML5触摸事件演化tap事件介绍
2016/03/25 HTML / CSS
Topman美国官网:英国著名的国际平价时尚男装品牌
2017/12/22 全球购物
求职推荐信
2013/10/28 职场文书
京剧自荐信
2014/01/26 职场文书
揠苗助长教学反思
2014/02/04 职场文书
师德师风自我剖析材料
2014/09/27 职场文书
村党的群众路线教育实践活动总结材料
2014/10/31 职场文书
2014教师评职称工作总结
2014/11/10 职场文书
物业保安辞职信
2015/05/12 职场文书
2016新年致辞
2015/08/01 职场文书
golang 接口嵌套实现复用的操作
2021/04/29 Golang
实例详解Python的进程,线程和协程
2022/03/13 Python