用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 相关文章推荐
通用JS事件写法实现代码
Jan 07 Javascript
jQuery 标题的自动翻转实现代码
Oct 14 Javascript
JS 表单验证大全
Nov 23 Javascript
jQuery图片轮播的具体实现
Sep 11 Javascript
javaScript array(数组)使用字符串作为数组下标的方法
Nov 19 Javascript
jquery validate 自定义验证方法介绍 日期验证
Feb 27 Javascript
javascript实用方法总结
Feb 06 Javascript
使用jQuery Mobile框架开发移动端Web App的入门教程
May 17 Javascript
AngularJS使用ng-inlude指令加载页面失败的原因与解决方法
Jan 19 Javascript
详解从零搭建 vue2 vue-router2 webpack3 工程
Nov 22 Javascript
微信小程序访问豆瓣电影api的实现方法
Mar 31 Javascript
JS实现的自定义map方法示例
May 17 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实现的获取网站备案信息查询代码(360)
2013/09/23 PHP
详解php的socket通信
2015/08/11 PHP
深入理解PHP中的empty和isset函数
2016/05/26 PHP
PHP基于GD库实现的生成图片缩略图函数示例
2017/07/05 PHP
laravel 框架配置404等异常页面
2019/01/07 PHP
PHP文件上传小程序 适合初学者学习!
2019/05/23 PHP
JQUERY对单选框(radio)操作的小例子
2013/04/25 Javascript
BAT及各大互联网公司2014前端笔试面试题--JavaScript篇
2014/10/29 Javascript
使用JavaScript和C#中获得referer
2014/11/14 Javascript
JavaScript检查子字符串是否在字符串中的方法
2016/02/03 Javascript
去除html代码里面的script正则方法
2016/05/19 Javascript
JavaScript中的Object对象学习教程
2016/05/20 Javascript
聊一聊JS中this的指向问题
2016/06/17 Javascript
微信小程序 使用picker封装省市区三级联动实例代码
2016/10/28 Javascript
vue中element 上传功能的实现思路
2018/07/06 Javascript
微信小程序实现顶部导航特效
2019/01/28 Javascript
webpack4实现不同的导出类型
2019/04/09 Javascript
Vue实现开心消消乐游戏算法
2019/10/22 Javascript
在IIS服务器上以CGI方式运行Python脚本的教程
2015/04/25 Python
python使用os.listdir和os.walk获得文件的路径的方法
2017/12/16 Python
Python自动化运维之Ansible定义主机与组规则操作详解
2019/06/13 Python
python实现在函数图像上添加文字和标注的方法
2019/07/08 Python
利用CSS3的border-radius绘制太极及爱心图案示例
2016/05/17 HTML / CSS
Clarins娇韵诗美国官网:法国天然护肤品牌
2016/09/26 全球购物
PUMA澳大利亚官方网站:德国运动品牌
2018/10/19 全球购物
以工厂直接定价的传奇性能:Ben Hogan Golf
2019/01/04 全球购物
Ruby如何创建一个线程
2013/03/10 面试题
购房协议书
2014/04/11 职场文书
小班上学期评语
2014/05/05 职场文书
三八妇女节趣味活动方案
2014/08/23 职场文书
2014年团员学习十八大思想汇报
2014/09/13 职场文书
拾金不昧表扬信
2015/01/16 职场文书
考察邀请函范文
2015/01/31 职场文书
画展观后感
2015/06/17 职场文书
新闻稿标题
2015/07/18 职场文书
JavaScript展开运算符和剩余运算符的区别详解
2022/02/18 Javascript