最近写了一个上传文件的需求,可累,我们的项目需求要求如下:
- 兼容拖拽上传和点击上传文件,可替换当前选择的文件,所以每次上传只能上传一个文件
- 上传并不是直接上传,需要有一个给用户再次选择的时候,如下图
那按照常规写法,我就这样写了:
html
<el-upload v-if="!fileValue || statusManage === 'notImportStatus'" @click.capture="actionClick"
action="" class="upload_class" drag :show-file-list="false" :limit="1" :before-upload="beforeUPload"
:on-exceed="exceedFile">
<template v-if="statusManage === 'notImportStatus'">
<img class="fileIcon" src="@/assets/[email protected]">
<div class="file_name">{{ fileValue?.name }}</div>
<div class="file_operate flex textThemeColor">
<span class="hoverPointer" id="add-btn"> 重新上传</span>
<span class="hoverPointer" id="delete-btn">删除</span>
<!-- @click.stop="deleteFile" -->
</div>
<div class="button2 primary" id="import-btn">立即导入</div>
<!-- @click.stop="clickImport" -->
</template>
<template v-else>
<img class="fileIcon" src="@/assets/[email protected]">
<div class="flex">将文件拖拽至此区域,或
<div class="textThemeColor" id="add-btn">
点击添加
</div>
</div>
<div class="limit">支持...xsl 格式,限1,000M以内</div>
</template>
</el-upload>
js
let fileValue = ref<any>(null)
const beforeUPload = (file: any) => {
const isExcel =
file.type === 'application/vnd.ms-excel' ||
file.type ===
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
const isLt2M = file.size / 1024 / 1024 < 10
if (!isExcel)
ElMessageBox({
title: '温馨提示',
message: '上传文件只能是 xls / xlsx 格式!',
type: 'warning'
})
if (!isLt2M)
ElMessageBox({
title: '温馨提示',
message: '上传文件大小不能超过 10MB!',
type: 'warning'
})
importStatus.value = EImportState.NotImport
fileValue.value = file
return isExcel && isLt2M
}
// 文件数超出提示
const exceedFile = () => {
ElMessage.warning('最多只能上传一个文件!')
}
然而这样写后上传文件,总是会提示 然而就只上传了一个文件,提示的很莫名其妙,并且浏览器也会请求我上传的文件
给我搞得很懵。 最后跟同事请教下:说可能是el-upload 自动上传导致的,于是 设置
:auto-upload="false"
并且加上 :file-list="fileList"
,之前的 :before-upload="beforeUPload"
改成 :on-change="handleChange"
html
<el-upload :auto-upload="false" :file-list="fileList" :on-change="handleChange"
v-if="!fileValue || statusManage === 'notImportStatus'" @click.capture="actionClick" action=""
class="upload_class" drag :show-file-list="false" :limit="1" :on-exceed="exceedFile">
<template v-if="statusManage === 'notImportStatus'">
<img class="fileIcon" src="@/assets/[email protected]">
<div class="file_name">{{ fileValue?.name }}</div>
<div class="file_operate flex textThemeColor">
<span class="hoverPointer" id="add-btn"> 重新上传</span>
<span class="hoverPointer" id="delete-btn">删除</span>
<!-- @click.stop="deleteFile" -->
</div>
<div class="button2 primary" id="import-btn">立即导入</div>
<!-- @click.stop="clickImport" -->
</template>
<template v-else>
<img class="fileIcon" src="@/assets/[email protected]">
<div class="flex">将文件拖拽至此区域,或
<div class="textThemeColor" id="add-btn">
点击添加
</div>
</div>
<div class="limit">支持...xsl 格式,限1,000M以内</div>
</template>
</el-upload>
js
let fileValue = ref<any>(null)
const handleChange = (file: any, fileList2: any) => {
if (!fileList2) return false
const allowedTypes = [
'application/vnd.ms-excel', // .xls
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' // .xlsx
]
// 检查文件类型
if (!allowedTypes.includes(file.raw.type)) {
ElMessageBox({
title: '温馨提示',
message: '上传文件只能是 xls / xlsx 格式!',
type: 'warning'
})
fileList.value = []
return
}
importStatus.value = EImportState.NotImport
// 如果是 Excel 文件,更新文件列表 ---这部很重要
fileList.value = fileList2
fileValue.value = fileList2[0]
}
// 文件数超出提示
const exceedFile = (files: any[]) => {
if (files.length > 1) {
ElMessage.warning('最多只能上传一个文件!')
} else {
// 这部也重要
fileValue.value = files[0]
}
}
使用 :on-change
需要注意的是,在导入的时候需要注意下:
js
const formData = new FormData()
// 这里append 是 fileValue.value.raw,而不是fileValue.value
formData.append('file', fileValue.value.raw)
const importApi = await apiPostImportData({
encourageTypeId: defaultProps.type,
file: formData
})
最后成功解决上述问题,想要完整代码的可以call我!~~