el-upload结合表单使用
项目需求:在表单中需要上传图片到服务器,并且只有在点击表单的确定按钮时图片以及表单数据才会传到服务器,需要在前端实现下载、上传、预览等需求
el-upload代码
<el-upload
action="#"
:on-change="handleBeforeUpload"
list-type="picture-card"
:accept="types"
:auto-upload="false"
multiple="true"
:before-upload="handleBeforeUpload"
:limit="6"
ref="upload">
<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" @click="handlePictureCardPreview(file)" >
<i class="el-icon-zoom-in"></i>
</span>
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleDownload(file)">
<i class="el-icon-download"></i>
</span>
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete"></i>
</span>
</span>
</div>
<template #tip>
<div class="el-upload__tip">
.jpg/.png/.jpeg类型的文件可以上传大小不能超过5MB.
</div>
</template>
</el-upload>
<el-dialog :visible.sync="dialogVisible" :modal-append-to-body='false' >
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
效果图如下
js代码
//el-upload方法
//删除
handleRemove(file) {
let uploadList = this.$refs.upload.uploadFiles;
// let index = uploadList.findIndex((fileItem)=>{
// return fileItem.uid = file.name
// })
let index = uploadList.indexOf(file)
uploadList.splice(index, 1)
this.imgList = uploadList
},
//预览
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
//下载
handleDownload(file) {
this.downFile(file.url, file.name)
},
downFile(url, linkDownload) {
fetch(url) //使用fetch函数发送一个GET请求到指定的URL,获取文件的响应对象。
.then(response => response.blob()) //通过.then方法链,将响应对象转换为Blob数据(文件的二进制数据)。
.then(blob => { //再次使用.then方法链,处理获取到的Blob数据。
const link = document.createElement('a'); //使用document.createElement创建一个<a>节点。
link.href = URL.createObjectURL(blob); //通过URL.createObjectURL方法,将Blob数据转换成URL对象,然后将该URL赋值给link的href属性。这一步相当于生成了一个临时URL,供下载使用。
link.download = linkDownload; // 替换为你要保存的文件名和扩展名(设置用户下载文件时使用的文件名和扩展名)
link.click(); //调用click方法模拟用户点击链接,从而触发浏览器的文件下载行为。
URL.revokeObjectURL(link.href); // 释放URL对象资源(使用URL.revokeObjectURL方法释放之前创建的URL对象资源,避免内存泄漏)
})
.catch(error => {
console.error('下载失败:', error);
});
},
//限制大小
handleBeforeUpload (file) {
if (file.size > this.maxSize) {
ybsModal.message({status: 'warning', content: `文件大小超过了${this.maxSize / (1024 * 1024)}MB的限制`});
this.handleRemove(file)
}
},
以上js代码对应着图片的删除,预览,下载,以及在上传的时候判断图片大小
问题解决思路
当点击确定按钮的时候需要将表单数据和图片一起发送到后端(我这里是项目需求所需,当然你也可以分开两次发送:第一次数据,第二次图片)
在发送图片的时候需要将图片转为base64编码,要想和数据一起发送只有通过base64发送
确定按钮js方法
async test(form){
const {sid} = form
let fileList = this.$refs.upload.uploadFiles
form.fileList = await this.toBase64(fileList);
//调用ajax 。。。 将form作为data发送即可
},
async toBase64(files) {
const reader = new FileReader();
let fileListBase64 = []
for (let file of files) {
if (file.raw) {
await this.getBase64(file.raw).then(res => {
fileListBase64.push(res)
})
} else {
//将url地址转为base64 (这是后端回显的url,后端通过将数据流
//写入到了response当中)
await this.urlToBase64(file.url).then(res => {
fileListBase64.push(res);
})
}
}
return fileListBase64;
},
//通过url地址将图片转为base64
async urlToBase64(imageUrl) {
return new Promise((resolve, reject) => {
let canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
let img = new Image()
img.crossOrigin = 'Anonymous' // 解决Canvas.toDataURL 图片跨域问题
img.src = imageUrl
img.onload = function () {
canvas.height = img.height
canvas.width = img.width
ctx.fillStyle = '#fff' // canvas背景填充颜色默认为黑色
ctx.fillRect(0, 0, img.width, img.height)
ctx.drawImage(img, 0, 0) // 参数可自定义
const dataURL = canvas.toDataURL('image/png', 1) // 获取Base64编码
resolve(dataURL)
canvas = null // 清除canvas元素
img = null // 清除img元素
}
img.onerror = function () {
reject(new Error('Could not load image at ' + imageUrl))
}
})
},
async getBase64(file) {
return new Promise(function (resolve, reject) {
let reader = new FileReader();
let imgResult = "";
reader.readAsDataURL(file);
reader.onload = function () {
imgResult = reader.result;
};
reader.onerror = function (error) {
reject(error);
};
reader.onloadend = function () {
resolve(imgResult);
};
});
},
效果图如下
可以看到我图片被我转为base64给发送到springboot的后端,而后端是通过**List< string >**的格式来接收图片的base64字符串的(因为我是多张图片,如果只有一张可以改String即可)
后端数据转换
博客连接:https://blog.csdn.net/qq_45774406/article/details/137516892?spm=1001.2014.3001.5501
人只要有一种向上的精神,朝着自己的目标一步步努力,成功的机会就会越来越大。是块金子,无论在哪,总是会发光的!!!