开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 19 天,点击查看活动详情
上传图片进度管控
首先图片上传进度在没有开始上传的时候进度一定是%0,然后使用fromdata上传文件。axios封装了一个方法,onUploadProgress,文件上传过程中会触发多次。每次会返回一个图片传输的进度和文件的总大小,简单的数学公式,使用当前传送完毕的数据(loaded)除以文件总大小,就得到了文件的已经传出的百分比了,然后乘以100,就是该文件上传的进度了
let formData = new FormData()
formData.append('file', file)
formData.append('filename', file.name)
const res = await uploadSingle(formData, {
onUploadProgress(e) {
const { loaded, total } = e
const v = (loaded / total).toFixed(2) * 100 + '%'
},
})
多个文件上传进度管控
多个文件上传的进度管控和单个文件上传进度管控原理相同,只不过是写了一个循环,让每个图片都上传一下,这个案例是使用react搞的,所以会有个设置状态的方法,这些细节可以忽略
const tasklist = fileList.map(({ file, name, key },index) => {
let formData = new FormData()
formData.append('file', index==2?"file":file)
formData.append('filename', name)
return uploadSingle(formData, {
onUploadProgress(e) {
const { loaded, total } = e
const p = (loaded / total).toFixed(2) * 100 + '%'
setFileProgress(p, key)
},
})
.then((res) => {
if (!(res.code === 0)) {
throw new Error()
}
setFileProgress('100%', key)
return res
})
.catch(() => {
setFileProgress('0%', key)
return false
})
})
const res = await Promise.all(tasklist)
if (res.every((item) => item)) {
message.success('上传成功')
} else {
message.error('上传失败')
}
接口是这样的
export const uploadSingle = (fm, config={}) => {
return uploadHttp.post('/upload_single', fm, config)
}
事出有因
用户反馈:图片上传过程中,如果网络比较慢,会发现上传图片后没有一点反应,体验性很差,图片回显也比较慢
解决思路:通过XMLHttpRequest的progress来实现监听图片上传的进度,实时显示百分比,后台保存图片成功后再将图片转为Base64编码的字符串在前端显示出来,这样可以很大程度提高用户体验
需要达到的效果:
1、用户可以看到图片上传进度条百分比
2、提升图片回显速度(将图片转为Base64编码的字符串在前端显示)
axios 是对如下原生js封装
var xhr = new XMLHttpRequest();
//上传中设置上传的百分比
xhr.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
if (percentComplete == 100){
setTimeout(function () {
document.getElementById("showProgress").innerHTML = "已上传"+percentComplete+"%";
},1500)
}else{
document.getElementById("showProgress").innerHTML = "已上传"+percentComplete+"%";
}
}else {
document.getElementById("showProgress").innerHTML = "无法计算";
}
}, false);
//请求完成后执行的操作
xhr.addEventListener("load", function(evt){
var message = evt.target.responseText,
obj = eval("("+message+")");
$("#uploadImage").attr("src",obj);
document.getElementById("showProgress").style.display="none";
alert("上传成功!");
}, false);