用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 拖放效果实现代码
Jan 22 Javascript
基于jquery的DIV随滚动条滚动而滚动的代码
Jul 20 Javascript
JS的框架Polymer中的dom-if和is属性使用说明
Jul 29 Javascript
angularJS与bootstrap结合实现动态加载弹出提示内容
Oct 16 Javascript
如何判断Javascript对象是否存在的简单实例
May 18 Javascript
jquery判断类型是不是number类型的实例代码
Oct 07 Javascript
AngularJS动态菜单操作指令
Apr 25 Javascript
express框架实现基于Websocket建立的简易聊天室
Aug 10 Javascript
微信小程序用户位置权限的获取方法(拒绝后提醒)
Nov 15 Javascript
jQuery实现动态添加和删除input框实例代码
Mar 26 jQuery
微信自定义分享链接信息(标题,图片和内容)实现过程详解
Sep 04 Javascript
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
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查看session内容的函数
2008/08/27 PHP
PHP企业级应用之常见缓存技术篇
2011/01/27 PHP
PHP连接Access数据库的方法小结
2013/06/20 PHP
PHPer 需要了解的 5 个 Composer 小技巧
2014/08/18 PHP
Yii的Srbac插件用法详解
2016/07/14 PHP
Linux系统中为php添加pcntl扩展
2016/08/28 PHP
Yii2配置Nginx伪静态的方法
2017/05/05 PHP
一个加密JavaScript的开源工具PACKER2.0.2
2006/11/04 Javascript
JavaScript flash复制库类 Zero Clipboard
2011/01/17 Javascript
php+js实现倒计时功能
2014/06/02 Javascript
关于JS数组追加数组采用push.apply的问题
2014/06/09 Javascript
javascript基础语法学习笔记
2016/01/04 Javascript
JS使用eval()动态创建变量的方法
2016/06/03 Javascript
JS实用技巧小结(屏蔽错误、div滚动条设置、背景图片位置等)
2016/06/16 Javascript
利用vue实现模态框组件
2016/12/19 Javascript
jQuery实现单击按钮遮罩弹出对话框效果(1)
2017/02/20 Javascript
详解AngularJS用Interceptors来统一处理HTTP请求和响应
2017/06/08 Javascript
去掉vue 中的代码规范检测两种方法(Eslint验证)
2018/03/21 Javascript
JS与CSS3实现图片响应鼠标移动放大效果示例
2018/05/04 Javascript
微信小程序如何利用getCurrentPages进行页面传值
2019/07/01 Javascript
[07:54]DOTA2 MV《我的动力鞋》 ImbaTV 出品
2014/11/21 DOTA
[06:45]DOTA2-DPC中国联赛 正赛 Magma vs LBZS 选手采访
2021/03/11 DOTA
Django中redis的使用方法(包括安装、配置、启动)
2018/02/21 Python
python和shell监控linux服务器的详细代码
2018/06/22 Python
Html5移动端网页端适配(js+rem)
2021/02/03 HTML / CSS
Beauty Expert美国/加拿大:购买奢侈美容产品
2018/12/05 全球购物
英国护发和美妆在线商店:Klip Shop
2019/03/24 全球购物
澳大利亚排名第一的露营和户外设备在线零售商:Outbax
2020/05/06 全球购物
学子宴答谢词
2014/01/25 职场文书
企业办公室主任岗位职责
2014/02/19 职场文书
2014年扶贫工作总结
2014/11/18 职场文书
2014年体育教师工作总结
2014/12/03 职场文书
毕业生就业推荐表自我鉴定
2019/06/20 职场文书
合理缓解职场压力,让你随时保持最佳状态!
2019/06/21 职场文书
创业计划书之干洗店
2019/09/10 职场文书
vue route新窗口跳转页面并且携带与接收参数
2022/04/10 Vue.js