用element的upload組件實(shí)現(xiàn)多圖片上傳和壓縮的示例代碼
我用vuex做狀態(tài)管理,七牛云做圖床。
項(xiàng)目地址:多圖片上傳組件
效果展示

項(xiàng)目執(zhí)行流程
首先,讓我們來分析一下實(shí)現(xiàn)多圖片上傳的流程:
- 前端向后端請求用來上傳圖片至服務(wù)器的token
- 后端為每張要上傳的圖片生成一個圖片名,并用這個圖片名生成token
- 后端將圖片名和token返回給前端
- 前端拿到token以后,將圖片上傳至服務(wù)器
- 上傳成功以后,前端將圖片名發(fā)給后端
- 后端將圖片名存入數(shù)據(jù)庫

項(xiàng)目實(shí)現(xiàn)過程
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 是圖片上傳前執(zhí)行的方法。關(guān)于該組件的其他用法可以在element的官方文檔查閱:Upload 上傳
2.對圖片進(jìn)行壓縮
// upload.vue
imgQuality: 0.5, //壓縮圖片的質(zhì)量
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) {
//對圖片進(jìn)行壓縮
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);
})
}
}
壓縮圖片實(shí)現(xiàn)起來比較簡單。就是在beforeUpload()方法里面return一個Promise,Promise里面我們把圖片的長度和寬度按比例進(jìn)行縮小,并把圖片畫到canvas上,然后把canvas轉(zhuǎn)成一個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,并發(fā)給前端,我用Python實(shí)現(xiàn)。
filetype = data.get('filetype')
# 構(gòu)建鑒權(quán)對象
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,開始向服務(wù)器上傳圖片
// vuex/state.js
imgName: [], //圖片名數(shù)組
// 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.上傳成功以后,將圖片名存入數(shù)據(jù)庫
// 用到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
}
//將信息發(fā)送給后端
this.actionPublish(obj)
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue實(shí)現(xiàn)錄音并轉(zhuǎn)文字功能包括PC端web手機(jī)端web(實(shí)現(xiàn)過程)
vue實(shí)現(xiàn)錄音并轉(zhuǎn)文字功能,包括PC端,手機(jī)端和企業(yè)微信自建應(yīng)用端,本文通過實(shí)例代碼介紹vue實(shí)現(xiàn)錄音并轉(zhuǎn)文字功能包括PC端web手機(jī)端web,感興趣的朋友跟隨小編一起看看吧2024-08-08
vue樹形結(jié)構(gòu)數(shù)據(jù)處理的方法總結(jié)
在項(xiàng)目開發(fā)的過程中,會經(jīng)常使用樹形結(jié)構(gòu)數(shù)據(jù),前后端交互都會對數(shù)據(jù)進(jìn)行處理,后端返回的數(shù)據(jù)前端有的時候不能直接使用需要轉(zhuǎn)換,本文小編整理了一些項(xiàng)目中用到的處理方法,需要的朋友可以參考下2023-11-11
vue+iview+less 實(shí)現(xiàn)換膚功能
這篇文章主要介紹了vue+iview+less 實(shí)現(xiàn)換膚功能,項(xiàng)目搭建用的vue—cli,css框架選擇的iview,具體操作流程大家跟隨腳本之家小編一起看看吧2018-08-08
Vue+Vite項(xiàng)目初建(axios+Unocss+iconify)的實(shí)現(xiàn)
一個好的項(xiàng)目開始搭建總是需要配置許多初始化配置,本文就來介紹一下Vue+Vite項(xiàng)目初建(axios+Unocss+iconify)的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02
關(guān)于antd-vue?a-menu菜單綁定路由的相關(guān)問題
這篇文章主要介紹了關(guān)于antd-vue?a-menu菜單綁定路由的相關(guān)問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10

