Vue 3 script setup 中文件上传需串联文件选择、上传发起、进度监听、结果反馈四环节:用 ref 存文件、@change 监听 input,axios.post 配 onUploadProgress 计算进度,结合 status 控制状态与 UI 反馈。

在 Vue 3 的 script setup 中处理文件上传,关键在于把「文件选择」「上传发起」「进度监听」「结果反馈」这四个环节串成可响应、可控制的逻辑链。不需要额外插件,用原生 API + axios 或 fetch 就能实现干净可控的上传流程。
绑定文件选择与触发上传
用 ref 保存选中的文件对象,@change 监听 <input type="file"> 的变化:
- 文件选择后立即存入
ref,避免后续取不到files[0] - 上传按钮用
:disabled="!file"控制可用状态,提升交互反馈 - 支持多文件时改用
event.target.files数组遍历处理
示例代码片段:
<input type="file" @change="onFileChange" />
<button @click="startUpload" :disabled="!file">开始上传</button>
立即学习“前端免费学习笔记(深入)”;
const file = ref(null)
const onFileChange = (e) => { file.value = e.target.files[0] }
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
用 axios 实现带进度的上传请求
axios.post 支持 onUploadProgress 回调,这是获取实时进度的核心方式:
- 必须传入
FormData对象,不能直接传file原始 Blob -
headers: { 'Content-Type': 'multipart/form-data' }不需要手动设,FormData会自动设置边界(boundary) - 进度回调中通过
progressEvent.loaded / progressEvent.total计算百分比
const uploadProgress = ref(0)
const startUpload = async () => {
if (!file.value) return
const formData = new FormData()
formData.append('file', file.value)
await axios.post('/api/upload', formData, {
onUploadProgress: (e) => {
if (e.lengthComputable) {
uploadProgress.value = Math.round((e.loaded / e.total) * 100)
}
}
})
}
封装进度通知为可复用逻辑
进度不是只给 UI 看的数字,它应能驱动状态切换(如“上传中”→“完成”)、触发提示、甚至暂停/取消:
- 定义
status响应式变量(如'idle' | 'uploading' | 'success' | 'error') - 上传前清空上一次的
uploadProgress和status - 利用
axios.CancelToken或AbortController实现取消(Vue 3.4+ 推荐后者) - 错误时捕获
err.response?.data?.message或err.message做友好提示
配合 UI 展示进度与反馈
模板中用 v-if 控制不同状态下的内容,避免堆砌冗余元素:
- 进度条:用
<div class="bar"><div :style="{ width: uploadProgress + '%' }"></div></div> - 文字提示:根据
status显示「正在上传…」「上传成功」「网络错误,请重试」 - 按钮状态联动:上传中禁用按钮,成功后重置为「重新上传」或跳转
不依赖第三方组件也能做到清晰、轻量、易调试的上传体验。

















