vue圖片壓縮與批量上傳方式
更新時間:2025年01月25日 08:39:45 作者:C8H9NO2
文章介紹了使用Vue和Element UI的el-upload組件實現(xiàn)圖片的批量上傳和壓縮功能,前端需引入image-conversion庫并設置相關(guān)屬性,關(guān)閉自動上傳,通過on-change事件校驗文件名和大小,并增加一個提交到服務器的按鈕
vue圖片壓縮與批量上傳
使用el-upload組件
支持批量上傳和圖片壓縮。
前端需要引入 image-conversion
- multiple設置為true,允許批量上傳
- auto-upload設置為false,關(guān)閉自動上傳
在on-change的時候校驗文件名和文件大小
增加一個上傳到服務器的按鈕
<template>
<div class="">
<el-upload ref="pictureUpload"
:multiple="true"
:action="uploadFileUrl"
list-type="picture-card"
:disabled="check"
:on-change="handleOnChange"
:before-upload="beforUpload"
:on-success="handleUploadSuccess"
:auto-upload="false"
:file-list="showFile">
<i slot="default"
class="el-icon-plus"></i>
<div slot="file"
slot-scope="{file}">
<img class="el-upload-list__item-thumbnail"
:src="file.url"
alt="">
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview"
:disabled="true"
@click="handlePictureCardPreview(file)">
<i class="el-icon-zoom-in"></i>
</span>
<span v-if="!check"
class="el-upload-list__item-delete"
@click="handleRemoveThis(file)">
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
<el-button style="margin-left: 10px;"
size="small"
v-if="!check"
type="success"
@click="submitUpload">圖片提交到服務器</el-button>
<el-dialog :visible.sync="dialogVisible"
title="預覽"
width="800"
append-to-body>
<img :src="dialogImageUrl"
style="display: block; max-width: 100%; margin: 0 auto;">
</el-dialog>
</div>
</template>
<script>
import { getToken } from "@/utils/auth";
import * as imageConversion from 'image-conversion';
import { delImg } from "@/api/system/vote"
export default {
name: 'jImageUpload',
props: ['imageUrl', 'check'],
data () {
return {
AllLoading: [],
oldImg: null,
dialogImageUrl: '',
checkUpload: false,
fileList: [],
returnFileList: [],
showFile: [],
urlStr: [],
editFile: [],
dialogVisible: false,
uploadFileUrl: process.env.VUE_APP_BASE_API + "/sys/minio/upload", // 上傳的圖片服務器地址
headers: {
Authorization: "Bearer " + getToken(),
},
};
},
mounted () { // 在mounted時候賦值,子組件只更新一次,后面重新選擇后展示此組件的數(shù)據(jù),不再更新
this.oldImg = this.imageUrl
this.stringToImage(this.oldImg)
},
watch: {
imageUrl: function (val) {
// // console.log('val')
// // console.log(val)
this.oldImg = val
this.stringToImage(this.oldImg)
}
},
created () {
},
methods: {
stringToImage (imageString) {
this.showFile = []
this.editFile = []
if (imageString != null && imageString != '' && imageString != undefined) {
this.urlStr = imageString.split(",");
this.urlStr.forEach(item => {
let obj = new Object();
let obj1 = new Object();
obj1.url = item;
if (item.indexOf("http") < 0) {
item = process.env.VUE_APP_BASE_MINIO_API + item;
}
obj.url = item;
this.showFile.push(obj);
this.editFile.push(obj1);
});
}
},
arryToString (arry) {
var imgString = ""
if (arry.length > 0) {
for (var i = 0; i < arry.length; i++) {
if (i < arry.length - 1) {
imgString += arry[i].url + ",";
} else {
imgString += arry[i].url
}
}
}
return imgString
},
// 點擊查看圖片
handlePictureCardPreview (file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
handleOnChange (file, fileList) {
if (file.name.indexOf(',') !== -1) {
this.msgError("上傳的文件名稱中不允許出現(xiàn)英文逗號!");
this.handleRemoveThis(file)
return false
} else {
const isLt2M = file.size / 1024 / 1024 < 1;
if (!isLt2M) {
console.log(file)
// return new Promise((resolve) => {
// 壓縮到600KB,這里的600就是要壓縮的大小,可自定義
imageConversion.compressAccurately(file.raw, 600).then(res => {
file.raw = new window.File([res], file.name, { type: file.type })
file.size = file.raw.size
this.fileList.push(file)
});
// })
} else {
this.fileList.push(file)
}
}
},
// 文件上傳
submitUpload () {
// 全屏禁用開啟
this.AllLoading = this.$loading({
lock: true,
text: '圖片上傳中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
let fileList = []
let { uploadFiles, action, data } = this.$refs.pictureUpload
// console.log(uploadFiles)
// uploadFiles.forEach(file => {
// imageConversion.compressAccurately(file.raw, 600).then(res => {
// file.raw = new window.File([res], file.name, { type: file.type })
// file.size = file.raw.size
// });
// })
// console.log(uploadFiles)
this.uploadFiles({
uploadFiles,
data,
action,
success: (response) => {
var res = JSON.parse(response)
// this.$refs.uploadFile.clearFiles();
// console.log(res)
this.msgSuccess("圖片上傳成功!")
this.AllLoading.close()
res.data.fileName.forEach(item => {
let obj = new Object();
let obj1 = new Object();
obj.url = process.env.VUE_APP_BASE_MINIO_API + item;
obj1.url = item;
this.editFile.push(obj1)
this.showFile.push(obj)
var imgString = this.arryToString(this.editFile)
this.$emit('returnUrl', imgString)
})
},
error: (error) => {
this.msgError("圖片上傳失??!")
this.AllLoading.close()
console.log('圖片上傳失敗!', error)
}
})
},
/**
* 自定義上傳文件
* @param fileList 文件列表
* @param data 上傳時附帶的額外參數(shù)
* @param url 上傳的URL地址
* @param success 成功回調(diào)
* @param error 失敗回調(diào)
*/
uploadFiles ({ uploadFiles, headers, data, action, success, error }) {
let form = new FormData()
// 文件對象
uploadFiles.map(file => form.append("filedatas", file.raw))
// 附件參數(shù)
for (let key in data) {
form.append(key, data[key])
}
let xhr = new XMLHttpRequest()
// 異步請求
xhr.open("post", action, true)
// 設置請求頭
xhr.setRequestHeader("Authorization", getToken());
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
success && success(xhr.responseText)
} else {
error && error(xhr.status)
}
}
}
xhr.send(form)
},
// 移除圖片
handleRemoveThis (file) {
// console.log(file)
// 在控件中移除圖片
this.$refs.pictureUpload.handleRemove(file)
// 獲取圖片在數(shù)組中的位置
var number = this.showFile.indexOf(file)
// 獲取返回的文件url中此文件的url
var file = process.env.VUE_APP_BASE_MINIO_API + this.editFile[number].url.toString()
var fileItemList = file.split('/')
// 執(zhí)行文件刪除
delImg(fileItemList[4]).then(response => {
// // console.log(response)
})
this.editFile.splice(number, 1)
this.showFile.splice(number, 1)
var imgString = this.arryToString(this.editFile)
this.$emit('returnUrl', imgString)
},
// 上傳前
beforUpload (file) {
console.log("上傳之前")
console.log(file)
if (file.name.indexOf(',') !== -1) {
this.msgError("上傳的文件名稱中不允許出現(xiàn)英文逗號!");
return false
} else {
// this.checkUpload = true
this.fileList.push(file)
const isLt2M = file.size / 1024 / 1024 < 1;
if (!isLt2M) {
return new Promise((resolve) => {
// 壓縮到100KB,這里的100就是要壓縮的大小,可自定義
imageConversion.compressAccurately(file.raw, 600).then(res => {
resolve(res);
});
})
}
}
},
// 上傳成功
handleUploadSuccess (res, file, fileList) {
// this.checkUpload = false
// console.log("上傳成功")
// console.log(res)
// console.log(fileList)
console.log(this.$refs.pictureUpload.uploadFiles)
this.$message.success("上傳成功");
// fileList.forEach(item => {
// let obj = new Object();
// let obj1 = new Object();
// if (item.response !== undefined) {
// obj.url = process.env.VUE_APP_BASE_MINIO_API + item.response.fileName;
// obj1.url = item.response.fileName;
// this.editFile.push(obj1)
// this.showFile.push(obj)
// var imgString = this.arryToString(this.editFile)
// this.$emit('returnUrl', imgString)
// }
// })
let obj = new Object();
let obj1 = new Object();
obj.url = process.env.VUE_APP_BASE_MINIO_API + res.fileName;
obj1.url = res.fileName;
this.editFile.push(obj1)
this.showFile.push(obj)
var imgString = this.arryToString(this.editFile)
this.$emit('returnUrl', imgString)
},
handleUploadError () {
this.$message({
type: "error",
message: "上傳失敗",
});
this.loading.close();
},
},
};
</script>
<style scoped lang="scss">
.image {
position: relative;
.mask {
opacity: 0;
position: absolute;
top: 0;
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
transition: all 0.3s;
}
&:hover .mask {
opacity: 1;
}
}
</style>總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue-router 報錯NavigationDuplicated的解決方法
這篇文章主要介紹了Vue-router 報錯NavigationDuplicated的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-03-03
import.meta.glob() 如何導入多個目錄下的資源(最新推薦)
import.meta.glob() 其實不僅能接收一個字符串,還可以接收一個字符串數(shù)組,就是匹配多個位置,本文給大家介紹import.meta.glob() 如何導入多個目錄下的資源,感興趣的朋友一起看看吧2023-11-11
詳解如何將 Vue-cli 改造成支持多頁面的 history 模式
本篇文章主要介紹了詳解如何將 Vue-cli 改造成支持多頁面的 history 模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11
關(guān)于vue-cli-service:command?not?found報錯引發(fā)的實戰(zhàn)案例
這篇文章主要給大家介紹了關(guān)于vue-cli-service:command?not?found報錯引發(fā)的相關(guān)資料,文中通過實例代碼將解決的過程介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2023-02-02
vue項目如何使用$router.go(-1)返回時刷新原來的界面
這篇文章主要介紹了vue項目如何使用$router.go(-1)返回時刷新原來的界面問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09

