在Element Plus组件库Upload组件中的on-success钩子多次上传仅响应一次的解决方法
一、问题的描述
- 使用Element Plus组件库Upload组件的action方式实现多文件上传功能时,发现在上传文件后,on-success 钩子仅响应了一次。无论上传多少次图片,仅能通过on-success 钩子的 uploadFiles 参数获取到上传的第一个图片。
- 通过查看控制台,发现除第一个上传的status为success外,其余图片状态均是uploading。
二、问题的分析
action属性和file-list属性的描述
名称 | 描述 | 类型 | 默认值 | 必填 | action | 请求 URL | string | — | 是 | file-list / v-model:file-list | 默认上传文件 | UploadUserFile[] | [] | 否 |
- file-list 的官方描述为默认上传文件,在实际使用中,还可以用做对文件上传列表的记录。
- 为使其正常记录文件上传列表,需要在 handleAvatarSuccess 文件上传成功时的钩子 和 handleRemove 文件列表移除文件时的钩子中使用 uploadFiles 参数来更新 file-list。
因此,不难发现解决问题的方案:
- 首先定义Upload组件中的 file-list 属性
// @template
<el-upload
action="#"
:file-list="fileList"
:on-success="handleAvatarSuccess" //文件上传成功时的钩子
:on-remove="handleRemove" //文件列表移除文件时的钩子
>
</el-upload>
- 在 handleAvatarSuccess 文件上传成功时的钩子 和 handleRemove 文件列表移除文件时的钩子中使用 uploadFiles 参数来更新 Filelist。
// @script setup lang="ts" 组合式API
const fileList = ref<UploadUserFile[]>([])
//文件上传成功时的钩子
const handleAvatarSuccess: UploadProps['onSuccess'] = (...args) => {
const uploadFiles = args[2]
fileList.value = JSON.parse(JSON.stringify(uploadFiles))
}
//文件列表移除文件时的钩子
const handleRemove: UploadProps['onRemove'] = (...args) => {
const uploadFiles = args[1]
fileList.value = JSON.parse(JSON.stringify(uploadFiles))
}
- 经过更新 Filelist ,on-success 钩子响应正常,同时也可以通过 Filelist 来管理文件上传列表
三、完整代码示例
// @template
<el-form-item label="SPU图片" label-width="100px">
<el-upload
:file-list="fileList"
action="/api/admin/product/fileUpload"
list-type="picture-card"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
>
<el-icon><Plus /></el-icon>
</el-upload>
<el-dialog v-model="dialogVisible">
<el-image :src="dialogImageUrl" fit="contain" :lazy="true"></el-image>
</el-dialog>
</el-form-item>
// @script setup lang="ts" 组合式API
const fileList = ref<UploadUserFile[]>([])
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
//上传文件之前的钩子,参数为上传的文件, 若返回false或者返回 Promise 且被 reject,则停止上传。
const beforeAvatarUpload = (file: any) => {
if (file.type == 'image/jpeg' || file.type == 'image/png' || file.type == 'image/gif') {
if (file.size / 1024 / 1024 < 4) {
return true
} else {
ElMessage({
type: 'error',
message: '上传的图片大小需小于4M',
})
return false
}
} else {
ElMessage({
type: 'error',
message: '上传的图片需要为jpg、png或gif格式',
})
return false
}
}
//文件上传成功时的钩子
const handleAvatarSuccess: UploadProps['onSuccess'] = (...args) => {
const uploadFiles = args[2]
fileList.value = JSON.parse(JSON.stringify(uploadFiles))
}
//文件列表移除文件时的钩子
const handleRemove: UploadProps['onRemove'] = (...args) => {
const uploadFiles = args[1]
fileList.value = JSON.parse(JSON.stringify(uploadFiles))
}
//点击文件列表中已上传的文件时的钩子
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
dialogImageUrl.value = uploadFile.url!
dialogVisible.value = true
}
|