用element的upload组件实现多图片上传和压缩的示例代码

我用vuex做状态管理,七牛云做图床。

项目地址:多图片上传组件

效果展示

项目执行流程

首先,让我们来分析一下实现多图片上传的流程:

  • 前端向后端请求用来上传图片至服务器的token
  • 后端为每张要上传的图片生成一个图片名,并用这个图片名生成token
  • 后端将图片名和token返回给前端
  • 前端拿到token以后,将图片上传至服务器
  • 上传成功以后,前端将图片名发给后端
  • 后端将图片名存入数据库

项目实现过程

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)

以上是 用element的upload组件实现多图片上传和压缩的示例代码 的全部内容, 来源链接: utcz.com/z/323927.html

回到顶部