问题描述
假设已经上传了文件A,当再上传下一个文件B时,如果文件B不符合需求,比如大小超过10MB,提示上传失败并将文件B从上传队列中删除,但是同时会将已上传成功的上一个文件A也删除。
<el-upload name="uploadFiles" multiple
:action="fileUploadAction" :data="uploadData" :file-list="fileList"
:before-upload="beforeFileUpload"
:on-success="fileUploadSuccess"
:on-remove="fileUploadRemove"
accept=".jpg,.jpeg,.png,.gif,.pdf,.JPG,.JPEG,.PBG,.GIF,.BMP,.PDF,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.DOC,.XLS,.PPT,.DOCX,.XLSX,.PPTX">
<el-button>
<i class="el-icon-document" />添加附件
</el-button>
<span slot="tip" class="el-upload__tip ml-3">
支持office文档、图片,单文件上传大小限制10MB,最多上传20个附件
</span>
</el-upload>
-------------------------------------------------------------------------
// 附件上传前校验
beforeFileUpload (file) {
const isLenLimit = this.fileList.length < 20;
const isLt10M = file.size / 1024 / 1024 < 10;
if (!isLenLimit) {
this.$message.error('最多只能上传20个附件');
}
if (!isLt10M) {
this.$message.error('请上传体积小于10MB的文件');
}
return isLenLimit && isLt10M;
},
// 附件删除
fileUploadRemove (file) {
this.fileList.splice(this.fileList.findIndex(item => item.url === file.url), 1)
},
解决方法
当文件上传失败的时候,会调用before-remove / on-remove钩子。
根据fileUploadRemove方法,file是上传失败的文件B的信息,此时this.fileList(保存上传成功的文件)中并没有保存文件B,因此findIndex会返回-1,导致最后会删除this.fileList数组中的最后一个数据项。
因此,在执行删除操作的时候,需要添加一些判断,确认文件是否需要被删除。
修改后的代码如下:
fileUploadRemove (file) {
if(file && file.status==="success"){
this.fileList.splice(this.fileList.findIndex(item => item.url === file.url), 1)
}
}
成品:
<template>
<el-upload
:before-upload="beforeUpload"
:file-list="fileList"
style="height: 148px"
action
:limit="3"
list-type="picture-card"
accept=".jpg,.jpeg,.png,.bmp"
:http-request="uploadImg"
:on-exceed="handleExceed"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove">
<i class="el-icon-plus"></i>
</el-upload>
</template>
<script>
beforeUpload (file) { //图片上传前大小、类型、宽高限制
if (file.type.indexOf('image') < 0) {
this.$message.error('图片格式不正确')
return false
}
if (file.size > 2 * 1024 * 1024) {
this.$message.error('图片大小超过2M')
return false
}
return new Promise((resolve, reject) => {
let _URL = window.URL || window.webkitURL
let img = new Image()
img.onload = function () {
let valid = img.width / img.height === 4 / 3
valid ? resolve() : reject()
}
img.src = _URL.createObjectURL(file)
}).then(
() => {
return file
}, () => {
this.$message.error('图片尺寸比例必须为4/3')
return Promise.reject()
})
},
upImgToString () { //上传的图片拼接成字符串供前后端交互
this.ruleForm.articleImage = this.fileList.reduce((p, c) => p + c.url + ',', '')
this.$refs.ruleForm.validateField('articleImage')
},
handleExceed (files, fileList) { //上传图片超过3个提示
this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
},
handleRemove (file) { //删除图片
if (file && file.status == 'success') {
const fu = file.uid
const num = this.fileList.findIndex(value => value.uid === fu)
this.fileList.splice(num, 1)
this.upImgToString()
}
},
handlePictureCardPreview (file) { //上传的图片大图预览
this.dialogImageUrl = file.url
this.dialogVisible = true
},
uploadImg (fileObj) { //上传图片
const loading = this.$loading({
lock: true,
text: '上传中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
let formData = new FormData()
formData.append('file', fileObj.file)
this.gethosuploadFile(formData)
.then(data => {
if (data.code == 200) {
this.fileList.push({'url': data.data})
this.upImgToString()
loading.close()
} else {
this.$message(data.message)
}
})
.catch(msg => {
this.$message({
type: 'info',
message: '服务器异常!'
})
})
},
</script>