Ant Design Vue Upload 组件完整指南文件上传、拖拽交互与自定义上传实现【免费下载链接】ant-design-vue An enterprise-class UI components based on Ant Design and Vue. 项目地址: https://gitcode.com/gh_mirrors/an/ant-design-vue文件上传是 Web 应用中最高频的数据录入场景之一。Ant Design Vue 的Upload组件不仅封装了点击选择、拖拽上传、进度展示与列表管理等完整能力还通过beforeUpload、customRequest、itemRender等扩展点把上传逻辑的定制权交还开发者。本文以 components/upload/index.zh-CN.md 官方文档为主体结合仓库源码与示例系统讲解 Upload 组件的 API、事件、数据模型及底层实现原理读完即可在真实项目中完成从基础上传到深度定制的全部实践。何时使用 Upload上传是将信息网页、文字、图片、视频等通过网页或者上传工具发布到远程服务器上的过程。在以下场景中应当使用 Upload 组件需要上传一个或一批文件时需要向用户展示上传进度时需要使用拖拽交互来完成文件选择时。仓库中的 demo 目录提供了 17 个官方示例basic.vue、drag.vue、picture-card.vue、directory.vue、max-count.vue、custom-render.vue等覆盖了从基础点击上传到自定义渲染的几乎全部使用形态下文会逐一展开。基础用法点击上传经典款式下用户点击按钮弹出文件选择框。以 demo/basic.vue 为例template a-upload v-model:file-listfileList namefile actionhttps://www.mocky.io/v2/5cc8019d300000980a055e76 :headersheaders changehandleChange a-button upload-outlined/upload-outlined Click to Upload /a-button /a-upload /template script langts setup import { ref } from vue; import { message } from ant-design-vue; import { UploadOutlined } from ant-design/icons-vue; import type { UploadChangeParam } from ant-design-vue; const handleChange (info: UploadChangeParam) { if (info.file.status ! uploading) { console.log(info.file, info.fileList); } if (info.file.status done) { message.success(${info.file.name} file uploaded successfully); } else if (info.file.status error) { message.error(${info.file.name} file upload failed.); } }; const fileList ref([]); const headers { authorization: authorization-text, }; /script这里有几个关键点v-model:file-list是 Vue 3 下的受控写法等价于:file-listupdate:file-list。在 Upload.tsx 的onInternalChange中可以看到组件内部会同时触发props[onUpdate:fileList]与props.onChange从而保证双向绑定与状态同步。action指定上传地址name指定发到后台的文件参数名默认fileheaders设置请求头。拖拽上传Upload.Dragger把文件拖入指定区域即可完成上传同样支持点击上传设置multiple后可以一次上传多个文件。参考 demo/drag.vuea-upload-dragger v-model:fileListfileList namefile :multipletrue actionhttps://www.mocky.io/v2/5cc8019d300000980a055e76 changehandleChange drophandleDrop p classant-upload-drag-icon inbox-outlined/inbox-outlined /p p classant-upload-textClick or drag file to this area to upload/p p classant-upload-hintSupport for a single or bulk upload./p /a-upload-dragger从源码看Dragger是对 Upload 的轻量封装Dragger.tsx 将type固定为drag并把height属性透传为容器高度而 Upload.tsx 在type drag分支下渲染拖拽区域监听drop、dragover、dragleave事件来切换drag-hover高亮样式同时通过dragState记录当前拖拽状态。API 详解主要参数参数说明类型默认值版本accept接受上传的文件类型对应原生input的 accept 属性string--action上传的地址string | (file) Promise--beforeUpload上传文件之前的钩子参数为上传的文件返回false则停止上传。支持返回 Promisereject 时停止上传resolve 时开始上传resolve 传入File或Blob对象则上传 resolve 传入的对象(file, fileList) boolean|Promise--customRequest覆盖默认的上传行为自定义上传实现function--data上传所需参数或返回上传参数的方法object | (file) object--directory支持上传文件夹booleanfalse3.0disabled是否禁用boolean--downloadIcon自定义下载 iconv-slot:iconRender{file: UploadFile}-3.0fileList已经上传的文件列表受控object[]--headers设置上传的请求头部object--iconRender自定义显示 iconv-slot:iconRender{file: UploadFile, listType?: UploadListType}-3.0isImageUrl自定义缩略图是否使用img /标签进行显示(file: UploadFile) boolean-3.0itemRender自定义上传列表项v-slot:itemRender{originNode, file, fileList, actions}-3.0listType上传列表的内建样式text、picture、picture-cardstringtext-maxCount限制上传数量。为 1 时始终用最新上传的文件代替当前文件number-3.0method上传请求的 http methodstringpost1.5.0multiple是否支持多选文件ie10开启后按住 ctrl 可选择多个文件booleanfalse-name发到后台的文件参数名stringfile-openFileDialogOnClick点击打开文件对话框booleantrue3.0previewFile自定义文件预览逻辑(file: File | Blob) PromisedataURL-1.5.0previewIcon自定义预览 iconv-slot:iconRender{file: UploadFile}-3.0progress自定义进度条样式仅支持typelineProgressProps{ strokeWidth: 2, showInfo: false }3.0removeIcon自定义删除 iconv-slot:iconRender{file: UploadFile}-3.0showUploadList是否展示 uploadList可传对象单独控制 showPreviewIcon、showRemoveIcon、showDownloadIconboolean | { showPreviewIcon?, showRemoveIcon?, showDownloadIcon? }trueshowDownloadIcon(3.0)supportServerRender服务端渲染时需要打开booleanfalse-withCredentials上传请求时是否携带 cookiebooleanfalse-其中部分参数的默认值可以在源码中直接印证Upload.tsx 的initDefaultProps声明了multiple: false、action: 、data: {}、accept: 、showUploadList: true、listType: text、supportServerRender: trueinterface.tsx 中则给出了完整的 TypeScript 类型定义例如action同时支持字符串、(file) string与(file) Promisestring三种形态data也支持对象或返回对象的函数。三个核心配置点的源码级解读action 与 data 的动态求值。在底层 vc-upload/AjaxUploader.tsx 的processFile中组件会先执行beforeUpload再分别求值action若是函数则await action(file)与data若是函数则await data(file)最后发起请求。这意味着你可以针对不同文件动态指定不同的上传地址与附加参数。beforeUpload 的完整语义。beforeUpload支持同步返回boolean也支持返回 Promise。对应实现见 Upload.tsx 的mergedBeforeUpload返回false或 Promise reject停止上传Promise resolve 一个File/Blob对象改传 resolve 出的对象常用于压缩图片、重命名文件等预处理返回字符串等其他值继续上传原文件。源码中还保留了transformFile作为兼容旧版本的废弃属性组件挂载时会输出 devWarning 提示改用beforeUpload见 Upload.tsx。maxCount 的截断逻辑。在onInternalChangeUpload.tsx中maxCount 1时取cloneList.slice(-1)保留最新文件其余情况slice(0, maxCount)截断列表——这就是为 1 时始终用最新文件替换当前文件的实现来源。事件事件名称说明回调参数版本change上传文件改变时的状态回调详见下文 change 详解function-download点击下载文件时的回调未指定时默认跳转到文件 url 对应的标签页function(file): void1.5.0drop文件被拖入上传区域时执行的回调(event: DragEvent) void3.0preview点击文件链接或预览图标时的回调function(file)-reject拖拽文件不符合 accept 类型时的回调function(fileList)-remove点击移除文件时的回调返回false则不移除支持返回 Promiseresolve(false) 或 reject 时不移除function(file): boolean | Promise3.0remove 的异步拦截。查看 Upload.tsx 的handleRemove组件通过Promise.resolve(mergedRemove(file))等待回调结果只有ret ! false时才会真正执行removeFileItem并从列表中移除同时把该文件标记为removed状态并调用底层upload.abort中止仍在进行的请求。测试用例 upload.test.js 也验证了getFileItem/removeFileItem工具函数的行为。UploadFile 数据模型UploadFile继承自浏览器原生File并附带额外属性用于渲染参数说明类型默认值版本crossOriginCORS 属性设置anonymous|use-credentials|-3.3.0name文件名string--percent上传进度number--status上传状态不同状态展示颜色也不同error|success|done|uploading|removed--thumbUrl缩略图地址string--uid唯一标识符不设置时会自动生成string--url下载地址string--更完整的类型定义见 interface.tsx除上述字段外还包含originFileObj原始文件对象、response服务端响应内容、error、linkProps下载链接额外的 HTML 属性、xhr等。在受控场景下未设置uid的文件会自动生成__AUTO__${timestamp}_${index}__格式的 uidUpload.tsx。change 详解上传中、完成、失败都会调用这个函数。文件状态改变的回调返回结构为{ file: { /* ... */ }, fileList: [ /* ... */ ], event: { /* ... */ }, }file当前操作的文件对象。{ uid: uid, // 文件唯一标识建议设置为负数防止和内部产生的 id 冲突 name: xx.png, // 文件名 status: done, // 状态有uploading done error removed response: {status: success}, // 服务端响应内容 linkProps: {download: image}, // 下载链接额外的 HTML 属性 xhr: XMLHttpRequest{ ... }, // XMLHttpRequest Header }fileList当前的文件列表。event上传中的服务端响应内容包含上传进度等信息高级浏览器支持。从源码可以追踪这些状态字段的来源Upload.tsx 中onSuccess会把文件置为done并写入percent: 100与response、xhronProgress置为uploading并更新percentonError置为error并写入error与response。这些回调由底层的 vc-upload/request.ts 在 XHR 生命周期中触发。测试 demo.test.js 与 upload.test.js 覆盖了beforeUpload返回 false、返回 Promise、返回 File 等多种链路。三种 listType 与列表渲染listType支持text默认、picture与picture-card三种内建样式。列表渲染实现在 UploadList/index.tsx 与 UploadList/ListItem.tsx列表用TransitionGroup包裹条目增删带有折叠动画collapseMotionpicture/picture-card模式下会自动生成缩略图watchEffect中对每个originFileObj调用previewFile默认实现是 utils.tsx 中的previewImage——用 200×200 的 canvas 将图片绘制为 dataURL且对 SVG 使用FileReader读取、其余类型用URL.createObjectURL结果写入thumbUrlpicture-card下预览、下载、删除操作悬浮在卡片上非上传中状态才展示上传中会显示进度条Progress组件typeline默认{ strokeWidth: 2, showInfo: false }进度条延迟 300ms 出现以缓解闪烁。图标与操作的自定义iconRender、previewIcon、downloadIcon、removeIcon均以作用域插槽形式接收{ file, listType? }itemRender则接收{ originNode, file, fileList, actions: { download, preview, remove } }允许你完全重写列表项 DOM见 interface.tsx 的ItemRender类型。组件内部默认图标逻辑在internalIconRenderUploadList/index.tsx上传中显示LoadingOutlinedpicture模式下图片文件显示PictureTwoTone其余显示FileTwoTone/PaperClipOutlined。FAQ 与常见问题排查服务端如何实现服务端上传接口实现可以参考成熟的 jQuery-File-Upload 服务端方案若需本地 mock可以参考基于 express 的上传服务示例通过multer或类似中间件接收multipart/form-data请求字段名与 Upload 的name属性默认file保持一致成功返回 JSON如{ status: success }该响应会写入info.file.response。手机设备如何选择相册或文件夹设置:capturenull即可。该属性在 interface.tsx 中定义为boolean | user | environment类型。如何显示下载链接使用fileList属性设置数组项的url属性进行展示控制当file.url存在时列表项的文件名会渲染为a链接支持linkProps附加download、rel等 HTML 属性点击默认在新标签页打开同时showUploadList的showDownloadIcon3.0 起可在done状态下展示下载按钮。相关行为见 ListItem.tsx 及测试 upload.test.js验证了linkProps既支持对象也支持 JSON 字符串。customRequest怎么使用customRequest用于完全接管上传请求适合对接自己的上传 SDK、分片上传或七牛/AWS 等云存储。它接收一个 options 对象包含action、data、file、headers、withCredentials、onProgress、onSuccess、onError等字段你需要自行发起请求并调用这些回调通知组件更新状态。未传customRequest时组件会使用默认的 XHR 实现 vc-upload/request.ts。为何fileList受控时上传不在列表中的文件不会触发onChange后续的status更新事件onChange事件仅作用于在列表中的文件因而fileList不存在对应文件时后续事件会被忽略。从源码看onSuccess/onProgress/onError都会先调用getFileItem(file, mergedFileList.value)做存在性检查文件不在列表中则直接 returnUpload.tsx。请注意在3.0.0-beta.10版本之前受控状态存在 bug导致不在列表中的文件也会触发。onChange为什么有时候返回 File 有时候返回{ originFileObj: File }历史原因在beforeUpload返回false时会返回 File 对象此时未真正上传组件会构造一个克隆的 File/Blob 并携带原文件的 uid见 Upload.tsx其他场景返回带originFileObj的对象。在下个大版本会统一返回{ originFileObj: File }对象。当前版本已经兼容所有场景下通过info.file.originFileObj获取原始 File 的写法你可以提前切换。为何有时 Chrome 点击 Upload 无法弹出文件选择框与组件本身无关原生上传也会失败。常见原因是 Chrome 升级未完成导致内核状态异常请重启 Chrome 浏览器让其完成升级工作。进阶深度定制实践路径结合以上 API 与源码可以归纳出几条进阶实践路径均可在 demo 中找到对应示例数量与类型限制maxCount控制总数参考max-count.vueacceptbeforeUpload拦截不合法文件参考upload-png-only.vue上传前处理在beforeUpload中压缩图片、重命名、校验大小返回新的 File/Blob参考transform-file.vue手动触发上传beforeUpload返回false阻止自动上传再通过customRequest或收集文件后统一提交参考upload-manually.vue受控列表用v-model:file-list或:file-listchange自行维护上传状态参考fileList.vue、defaultFileList.vue自定义渲染itemRender重写列表项、iconRender/previewIcon/removeIcon/downloadIcon自定义图标、progress定制进度条参考custom-render.vue、customize-progress-bar.vue、upload-custom-action-icon.vue、preview-file.vue目录上传开启directory参考directory.vue底层通过 vc-upload/traverseFileTree.ts 递归遍历文件夹中的文件头像/图片墙listTypepicture-cardacceptimage/*组合参考picture-card.vue、avatar.vue。小结Ant Design Vue 的 Upload 组件在单一组件内集成了文件选择、拖拽、目录上传、进度展示、列表管理与错误处理等完整能力同时通过beforeUpload、customRequest、itemRender等钩子保留了极强的可扩展性。理解其 API 语义与源码中的状态流转onBatchStart→onProgress→onSuccess/onError→change可以帮助你在实际业务中准确预测组件行为写出健壮的上传模块。若需深入源码可从 Upload.tsx、UploadList/index.tsx 与 vc-upload/AjaxUploader.tsx 三处入手。【免费下载链接】ant-design-vue An enterprise-class UI components based on Ant Design and Vue. 项目地址: https://gitcode.com/gh_mirrors/an/ant-design-vue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考