layui upload 的 choose 回调中必须立即执行 const currentFiles = obj.pushFile() 并保存文件队列,否则后续无法获取最新选择状态;批量删除需遍历 delete currentFiles[key],不可赋空对象或删除变量;UI 同步须配合 uploadInst.files = {} 和 uploadInst.reload()。

choose 回调里必须立刻保存 files 队列
layui upload 没有 clearFiles() 这类公开方法,所有批量删除操作都依赖你在 choose 回调中及时拿到并持有当前文件队列。一旦错过这个时机,obj.pushFile() 后续调用会返回空对象或旧快照,无法反映最新选择状态。
关键动作只有一行:const currentFiles = obj.pushFile(); —— 必须在 choose 函数开头就执行,且赋值给一个可被后续操作访问的变量(比如闭包变量或组件实例属性)。
- 不要等
done或error里再取,那时队列已过期 - 不要在全局作用域提前声明空对象然后试图“合并”,
obj.pushFile()每次返回的是全新对象,不是增量更新 - 如果用了
multiple: true,currentFiles是形如{"1612418956647-0": File, "1612418956647-1": File}的键值对,不是数组
批量删除就是遍历 delete 键
拿到 currentFiles 后,批量清空就是循环调用 delete currentFiles[key]。注意:只能删 key,不能删整个对象,否则 upload 实例内部状态会错乱,导致下次点击上传按钮仍发请求但无文件字段。
常见场景代码片段:
choose: function(obj) {
// ✅ 正确:立刻保存
this.filesQueue = obj.pushFile();
// ✅ 批量清空(比如用于单文件模式,只留最新一个)
const keys = Object.keys(this.filesQueue);
if (keys.length > 1) {
keys.slice(0, -1).forEach(key => delete this.filesQueue[key]);
}
// ✅ 或直接全清(用户点击「取消全部」按钮时)
// Object.keys(this.filesQueue).forEach(key => delete this.filesQueue[key]);
}
- 别写
this.filesQueue = {}—— 这会切断与 upload 内部引用的关系 - 别写
delete this.filesQueue—— 删除的是变量引用,不是对象属性 - DOM 列表(
.layui-upload-list)不会自动同步,需手动清空或等reload()
配合 reload() 才能刷新 UI 显示
删掉 filesQueue 里的键只是清了内存队列,UI 上的缩略图、文件名列表还挂着。必须主动触发重绘:
uploadInst.reload(); 是唯一可靠方式。它会清空 .layui-upload-list 内容,并根据当前 uploadInst.files(注意不是你存的 filesQueue)重新渲染 —— 所以你还得同步更新实例的 files 属性:
// 假设 uploadInst 是 render 返回的实例
uploadInst.files = {}; // 或 = []
uploadInst.config.elem.next('.layui-upload-list').html('');
uploadInst.reload();
- 仅调用
reload()不设置uploadInst.files,UI 可能残留旧项 - 仅清 DOM 不调
reload(),下次上传可能把已删文件一起发出去 -
form.reset()对 upload 完全无效,别试
弹窗场景下容易漏掉的清理点
如果 upload 渲染在 layer 弹窗里,用户选了文件但没上传就关闭弹窗,再打开时 UI 看似干净,但 filesQueue 和 uploadInst.files 仍在内存里。下次点上传,幽灵文件会悄悄提交。
解决办法是在弹窗打开回调里主动重置:
layer.open({
content: $('#uploadModal'),
success: function() {
// ✅ 每次打开都清空
if (uploadInst) {
uploadInst.files = {};
uploadInst.config.elem.next('.layui-upload-list').html('');
uploadInst.reload();
}
}
});
这个步骤常被忽略,尤其当 upload 实例是全局变量时——它不会随弹窗销毁自动回收。











