Vue文件上传组件通过emit事件驱动实现进度与结果回传,子组件监听XHR进度并节流emit on-progress,上传完成时emit on-success/on-error/on-cancel,父组件监听事件更新状态并配合props控制行为。
Vue 中文件上传组件通过 emit 向父组件回传进度与结果,核心在于子组件主动触发自定义事件,并携带实时数据;父组件监听对应事件并更新状态。这不是单纯的数据绑定,而是“事件驱动 + 状态同步”的组合实践。
在子组件内部(如封装的 Upload.vue),使用原生 XMLHttpRequest 或 axios 时,需监听 upload.onprogress,计算百分比后通过 emit 发出:
update:progress 或更语义化的 on-progress
xhr.upload.onprogress 回调中判断 e.lengthComputable,避免 NaNMath.round((e.loaded / e.total) * 100),再 emit('on-progress', { percent: value, loaded: e.loaded, total: e.total })
上传结束不是靠定时轮询,而是依赖请求的自然回调(onload、onerror、onabort):
on-success,携带后端返回的响应数据(如文件 ID、URL、原始文件名)on-error,附带错误信息(err.message 或后端 code/msg)on-cancel,便于父组件清理 UI 状态(如隐藏进度条、还原按钮文字){ status: 'success', data: res, file: currentFile }
父组件不能只写 @on-success="handleSuccess" 就完事,还需配合状态管理逻辑:
@on-progress="updateProgress" @on-success="handleUploadSuccess" @on-error="handleUploadError"
updateProgress 方法中直接更新本地 ref(如 progressPercent),驱动进度条渲染isUploading = false)、清空 input 的 value(避免重复选同一文件)、并可能触发后续操作(如提交表单)仅靠 emit 不够,父组件还需通过 props 向子组件传递必要控制参数:
:url —— 上传目标接口地址(动态传入,避免写死):headers —— 认证 token 或业务 header:max-size 和 :accept —— 前置校验,减少无效 emit:auto-upload —— 控制是否选完即传,还是由父组件统一触发