ant-design-vue Upload 组件完全指南:API 详解、拖拽上传与源码实现剖析
ant-design-vue Upload 组件完全指南API 详解、拖拽上传与源码实现剖析【免费下载链接】ant-design-vue An enterprise-class UI components based on Ant Design and Vue. 项目地址: https://gitcode.com/gh_mirrors/an/ant-design-vue本文以 ant-design-vue 官方文档 components/upload/index.en-US.md 为核心骨架系统讲解 Upload 组件的全部 API、事件模型、UploadFile 数据结构与 FAQ 高频问题并结合仓库源码Upload.tsx、interface.tsx、utils.tsx与 17 个官方 Demo 进行源码级佐证。读完本文你将掌握点击上传、拖拽上传、照片墙、手动上传、数量限制等完整实战方案并能理解beforeUpload拦截、change事件触发机制、缩略图生成等底层实现原理。Upload上传是表单类Data Entry组件中发布信息网页、文本、图片、视频等到远程服务器的核心入口。ant-design-vue 的 Upload 组件由点击上传的AUpload与拖拽上传的AUploadDragger即a-upload-dragger两个组件构成二者在 index.tsx 中被统一导出并注册为全局组件同时还导出了LIST_IGNORE常量与UploadDragger别名。一、何时使用 Upload上传是将信息网页、文本、图片、视频等通过网页或上传工具发布到远程服务器的过程。当出现以下需求时应使用 Upload 组件需要上传一个或多个文件需要展示上传进度过程需要支持拖拽文件到上传区域。从 Upload.tsx 的组件定义可见Upload 的默认配置为type: select点击选择模式、multiple: false、action: 、data: {}、accept: 、showUploadList: true、listType: text、supportServerRender: true。二、API 全量详解以下表格完整继承自官方文档并结合 interface.tsx 中的uploadProps()定义补充了底层类型约束说明。API 版本标记如3.0表示自 ant-design-vue 3.0 起可用。Property说明类型默认值版本accept接受上传的文件类型对应原生input accept属性string-action上传的 URL可以是字符串也可以是返回字符串或 Promise 的函数string | (file) Promise-beforeUpload上传前执行的钩子函数返回false或 rejected Promise 将停止上传(file, fileList) boolean|Promise-customRequest覆盖默认 xhr 行为用于自定义上传请求实现function-data上传所需参数可为对象或返回参数对象的函数object | function(file)-directory支持上传整个目录浏览器需支持 input-file-directorybooleanfalse3.0disabled禁用上传按钮boolean-downloadIcon自定义下载图标v-slot:iconRender{file: UploadFile}-3.0fileList已上传的文件列表受控object[]-headers设置请求头IE10 以上生效object-iconRender自定义显示图标v-slot:iconRender{file: UploadFile, listType?: UploadListType}-3.0isImageUrl自定义判断是否在缩略图中渲染img /(file: UploadFile) boolean-3.0itemRender自定义上传列表项v-slot:itemRender{originNode: VNode, file: UploadFile, fileList: object[], actions: { download, preview, remove }-3.0listType内置样式支持text、picture、picture-card三种stringtextmaxCount限制上传文件数量为1时用新文件替换当前文件number-3.0method上传请求的 HTTP 方法stringpost1.5.0multiple是否支持多选文件IE10 支持按住 CTRL 可多选booleanfalsename上传文件的字段名stringfileopenFileDialogOnClick点击时打开文件对话框booleantrue3.0previewFile自定义预览文件逻辑(file: File | Blob) PromisedataURL: string-1.5.0previewIcon自定义预览图标v-slot:iconRender{file: UploadFile}-3.0progress自定义进度条支持 ProgressProps仅typelineobject{ strokeWidth: 2, showInfo: false }3.0removeIcon自定义删除图标v-slot:iconRender{file: UploadFile}-3.0showUploadList是否显示默认上传列表可为对象以单独控制showPreviewIcon、showRemoveIcon、showDownloadIconboolean | { showPreviewIcon?, showRemoveIcon?, showDownloadIcon? }trueshowDownloadIcon(3.0)supportServerRender服务端渲染时需要开启booleanfalsewithCredentialsajax 上传携带 cookiebooleanfalse2.1 源码中的类型约束锦上添花在 interface.tsx 中uploadProps()定义了所有属性的 Vue 组件 prop 声明以下几点值得关注action与data均通过someType支持多类型action可以是string | ((file) string) | ((file) PromiseLikestring)data可以是Recordstring, unknown | ((file) PromiseRecordstring, unknown)。method被限定为POST | PUT | PATCH | post | put | patch。capture支持boolean | user | environment用于移动端相机调用这正是 FAQ 中移动端选择相册或文件夹问题的答案所在。transformFile与remove属性已被标记为deprecated官方建议分别改用beforeUpload与onRemove事件。Upload 组件在挂载时Upload.tsx会通过devWarning对已废弃用法给出控制台警告。progress的类型为UploadListProgressProps即OmitProgressProps, percent | type这与文档中仅支持typeline的说明一致。另外fileList支持v-model:file-list双向绑定在 Upload.tsx 中通过useMergedState合并受控的fileList与默认的defaultFileList并会自动为缺少uid的文件生成__AUTO__${timestamp}_${index}__形式的唯一标识onInternalChange中还会调用props[onUpdate:fileList]以支持 v-model 语法。三、事件events事件名说明参数版本change上传状态变化时的回调function-download点击下载文件的方法传入方法则执行自定义逻辑不传则默认跳转新 TABfunction(file): void1.5.0drop文件被拖拽到上传区域时执行的回调(event: DragEvent) void3.0preview点击文件链接或预览图标时执行的回调function(file)-reject拖入不符合 accept 的文件时执行的回调function(fileList)-remove点击删除文件按钮时执行返回 false 或 resolve(false)/reject 的 Promise 时阻止删除function(file): boolean | Promise3.03.1 事件源码行为说明change在 Upload.tsx 的onInternalChange中实现。其内部会先根据maxCount裁剪文件列表maxCount 1时slice(-1)只保留最新文件否则slice(0, maxCount)截取前 N 个再组装{ file, fileList, event? }参数向外派发。remove 的可取消机制handleRemoveUpload.tsx会通过Promise.resolve包装onRemove的返回值若结果为false则直接返回阻止删除删除成功后会将文件status置为removed、调用底层upload.value?.abort(currentFile)中止正在进行的请求并触发change。droponFileDropUpload.tsx会同步维护dragStatedrop/dragover/dragleave并在e.type drop时调用props.onDrop?.(e)。拖拽状态会反映到样式类上ant-upload-drag-hover、ant-upload-drag-uploading等见 Upload.tsx。download 默认行为在 UploadList/index.tsx 的onInternalDownload中若未传入onDownload且文件存在url则默认执行window.open(file.url)新开 TAB。四、UploadFile 数据结构UploadFile扩展自原生File并附加以下属性完整定义见 interface.tsxProperty说明类型默认值版本crossOriginCORS 设置属性anonymous|use-credentials|-3.3.0name文件名string-percent上传进度百分比number-status上传状态配置后显示不同样式error|success|done|uploading|removed-thumbUrl缩略图 URLstring-uid唯一标识未提供时自动生成string-url下载 URLstring-此外源码中UploadFile还包含size、lastModified、lastModifiedDate、originFileObj原始文件对象、response服务端响应、error、linkProps、type、xhr、preview等字段。其中originFileObj在兼容场景下用于追溯原始文件InternalUploadFile则强制要求携带originFileObj。4.1 文件对象的内部转换当用户选择文件后utils.tsx 中的file2Obj会将原生File转换为InternalUploadFile复制lastModified、lastModifiedDate、name、size、type、uid等字段初始化percent: 0并保留originFileObj指向原始文件。列表的增改删分别由updateFileList按 uid 替换或追加、getFileItem与removeFileItem按 uid 或 name 匹配完成。五、change 回调详解change 函数会在上传进行中、完成或失败时被调用。当上传状态变化时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 头信息 }fileList当前的文件列表。event服务端响应包含上传进度高级浏览器支持。在 Upload.tsx 中上传成功、进度、失败分别由onSuccess、onProgress、onError处理成功时解析 JSON 响应、将状态置为done、percent置为100并记录response与xhr进度更新时将percent写入event失败时记录error与response、状态置为error。三者都会先通过getFileItem校验文件是否仍在列表中已被移除则忽略事件再以updateFileList生成新列表并触发onInternalChange。一个典型的 change 使用方式来自官方 Demo demo/basic.vueconst 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.); } };六、三种内置列表样式listTypelistType支持三种取值源码类型定义为text | picture | picture-card见 interface.tsxtext默认样式仅显示文件名、状态与操作图标picture图片列表样式显示缩略图picture-card照片墙卡片样式上传按钮内嵌于列表末尾。在 UploadList/index.tsx 中有一个关键实现细节当listType为picture或picture-card时组件会通过watchEffect遍历文件列表对拥有originFileObjFile或Blob实例且尚无thumbUrl的文件调用默认的previewFile即 utils.tsx 中的previewImage异步生成缩略图并回填thumbUrl。previewImage内部使用 200×200 的 canvas 等比缩放绘制图片并将非图片文件解析为空字符串。照片墙的典型用法见 demo/picture-card.vue通过list-typepicture-card展示缩略图配合preview事件与a-modal实现点击放大预览并通过v-iffileList.length 8控制上传按钮在达到数量上限后消失。七、拖拽上传Upload.Dragger拖拽上传由a-upload-dragger实现。其源码 Dragger.tsx 非常简洁将type强制置为drag并把height属性转换为行内style.height数字自动加px后透传给AUpload。在 Upload.tsx 中type drag时会渲染带拖拽区域的包裹结构并通过onDrop、onDragover、onDragleave三个事件维护dragState最终生成ant-upload-drag、ant-upload-drag-uploading、ant-upload-drag-hover、ant-upload-disabled等样式类。官方示例 demo/drag.vuea-upload-dragger v-model:file-listfileList 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-hint Support for a single or bulk upload. Strictly prohibit from uploading company data or other band files /p /a-upload-dragger设置multiple后可一次拖入多个文件同时上传。八、受控列表与限制数量fileList / maxCountfileList受控通过v-model:file-listfileList或单向绑定:file-list控制上传列表。官方文档特别提醒受控 fileList 存在一个常见问题见 issue #2423change只在文件仍在列表中时触发文件被移出列表后会忽略其后续事件。同时需注意在3.0.0-beta.10之前存在一个 bug会导致文件不在列表中时事件依然触发。maxCount数量限制当maxCount为1时始终用最新上传的文件替换当前文件大于1时截取列表前 N 个。其实现位于 Upload.tsxmaxCount 1时cloneList.slice(-1)否则cloneList.slice(0, maxCount)。官方示例 demo/max-count.vue 分别演示了:max-count1与:max-count3的效果。九、手动上传beforeUpload 返回 false当需要自行控制上传时机如用户点击开始上传按钮后再提交时可让beforeUpload返回false拦截自动上传。其底层逻辑在 Upload.tsx 的mergedBeforeUpload中若beforeUpload返回false直接终止上传流程文件仅加入列表不发起请求若返回LIST_IGNORE常量Upload.tsx 中定义为__LIST_IGNORE_${Date.now()}__则文件连列表都不加入若返回对象则作为替换后的文件继续上传。官方示例 demo/upload-manually.vue 的完整流程const beforeUpload: UploadProps[beforeUpload] file { fileList.value [...(fileList.value || []), file]; return false; // 阻止自动上传 }; const handleUpload () { const formData new FormData(); fileList.value.forEach(file { formData.append(files[], file as any); }); uploading.value true; // 使用任意 AJAX 库发起上传 request(https://www.mocky.io/v2/5cc8019d300000980a055e76, { method: post, data: formData, }) .then(() { /* 清空列表、提示成功 */ }) .catch(() { /* 提示失败 */ }); };十、自定义请求customRequestcustomRequest用于覆盖默认的 XMLHttpRequest 上传行为实现自定义的上传请求如使用分片上传、第三方 SDK、WebSocket 等。其类型为(options: RcCustomRequestOptions) void见 interface.tsxRcCustomRequestOptions源自底层的vc-upload组件。官方文档建议参考 react-component/upload 的 customRequest 用法说明该方案同样适用于 ant-design-vue。十一、自定义图标与列表渲染iconRender / itemRendericonRender / removeIcon / previewIcon / downloadIcon均可通过作用域插槽自定义。在 UploadList/index.tsx 的internalIconRender中默认逻辑为上传中显示LoadingOutlinedtext列表显示PaperClipOutlinedpicture/picture-card列表根据isImageUrl判断显示PictureTwoTone图片或FileTwoTone文件picture-card上传中则显示本地化的上传中文案。itemRender完全自定义上传列表项接收{ originNode, file, fileList, actions: { download, preview, remove } }其中actions可直接触发对应操作。showUploadList 细分控制传对象{ showPreviewIcon, showRemoveIcon, showDownloadIcon }可分别控制预览、删除、下载图标的显隐。注意默认showDownloadIcon为false见 UploadList/index.tsx需显式开启。十二、FAQ 高频问题12.1 如何实现服务端上传接口可参考 jQuery-File-Upload 关于服务端上传接口的说明。rc-upload 中提供了一个基于 express 的 mock 示例可供参考。12.2 移动端如何选择相册或文件夹设置:capturenull即可。12.3 想显示下载链接怎么办为fileList中每一项设置url属性即可控制链接内容。12.4 如何使用 customRequest参考 react-component/upload 的 customRequest 文档。12.5 受控 fileList 中文件不在列表时为何不触发 change 的 status 更新change只在文件位于列表内时触发文件被移出列表后会忽略其后续事件。注意在3.0.0-beta.10之前存在 bug即使文件不在列表中事件仍会触发。12.6 为什么 change 有时返回 File 对象有时返回 { originFileObj: File }这是兼容性处理当beforeUpload返回false时返回 File 对象下一主版本将合并为{ originFileObj: File }。当前版本可通过info.file.originFileObj获取原始文件。从源码看Upload.tsx 在beforeUpload返回false时会尝试用new File([originFileObj], originFileObj.name, { type })构造克隆对象不支持 File 的环境回退到 Blob 并补齐 name、lastModified 等字段以保证 change 回调中的 file 形态兼容。12.7 为什么 Chrome 偶尔无法上传Chrome 更新可能破坏原生上传功能重启 Chrome 即可恢复。相关参考 issue#32672#32913#33988十三、进阶与 Form 表单集成的细节Upload 与 Form 组件深度集成。在 Upload.tsx 中通过useInjectFormItemContext()获取表单项上下文将id回填到上传按钮props.id ?? formItemContext.id.value从而支持点击 label 聚焦同时在onInternalChange中调用formItemContext.onFieldChange()通知表单校验更新Upload.tsx。当没有默认插槽内容或组件被禁用时会删除id以避免点击 label 误触发文件对话框Upload.tsx。十四、更多官方 Demo 一览components/upload/demo/目录下共提供 17 个可直接运行的示例除本文已引用的外还包括avatar.vue上传头像directory.vue整目录上传defaultFileList.vue默认文件列表非受控fileList.vue受控列表custom-render.vueitemRender 自定义列表项customize-progress-bar.vue自定义进度条preview-file.vue自定义预览逻辑transform-file.vue文件转换演示已废弃的 transformFile新项目应使用 beforeUploadupload-png-only.vue仅接受 png 类型upload-custom-action-icon.vue自定义操作图标。结语ant-design-vue 的 Upload 组件以选择上传 拖拽上传双形态覆盖了绝大多数文件上传场景配合beforeUpload拦截、customRequest自定义请求、maxCount数量限制、三种listType样式与丰富的插槽定制能力可灵活适配从简单的单文件上传到复杂的照片墙、手动批量上传等业务需求。理解其背后mergedBeforeUpload、onInternalChange、file2Obj等源码实现将帮助你在遇到受控列表、事件触发时机、兼容性等疑难问题时快速定位根因。【免费下载链接】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),仅供参考