文件上传和预览
核心思路
使用 URL.createObjectURL 实现即时本地预览,后台异步上传到 OSS,上传完成后替换为 OSS URL,并清理本地资源。
实现流程
1. 文件选择与验证
/* 先使用本地预览 */
const localPreviewUrl = URL.createObjectURL(file)
form.value.video.videoUrl = localPreviewUrl
form.value.video.originalVideoUrl = localPreviewUrl
/* 重置上传进度 */
videoUploadProgress.value = 0
/* 上传视频到OSS */
const uploadRes = await uploadFileToOSS({
file: file,
onProgress: (percent) => {
videoUploadProgress.value = percent
}
})
if (!uploadRes.success || !uploadRes.url) {
throw new Error(uploadRes.message || '视频上传失败')
}
/* 使用OSS URL替换本地预览URL */
const ossVideoUrl = uploadRes.url
form.value.video.videoUrl = ossVideoUrl
form.value.video.originalVideoUrl = ossVideoUrl
/* 清理本地预览URL */
URL.revokeObjectURL(localPreviewUrl)
2. 关键步骤
步骤 1:创建本地预览 URL
const localPreviewUrl = URL.createObjectURL(file)form.value.video.videoUrl = localPreviewUrl
- 立即生成 blob URL(如 blob:http://localhost:3000/xxx)
- 用户可立即看到预览,无需等待上传
步骤 2:异步上传到 OSS
const uploadRes = await uploadFileToOSS({
file: file,
onProgress: (percent) => {
videoUploadProgress.value = percent // 实时更新进度
}
})
- 使用 onProgress 回调更新进度条
- 上传过程不阻塞 UI
步骤 3:替换为 OSS URL
const ossVideoUrl = uploadRes.url
form.value.video.videoUrl = ossVideoUrl // 替换本地预览URL
步骤 4:清理本地资源
URL.revokeObjectURL(localPreviewUrl)
- 避免内存泄漏
- 仅在成功上传后清理
3. 错误处理
} catch (error) {
console.error('处理视频失败:', error)
ElMessage.error(error.message || '处理视频失败,请重试')
/* 清空文件选择 */
if (event.target) {
event.target.value = ''
}
} finally {
loading.value = false
}
技术优势
- 即时反馈:用户选择文件后立即看到预览
- 进度可视化:通过 onProgress 实时显示上传进度
- 内存管理:及时清理 blob URL,避免内存泄漏
- 无缝切换:从本地预览平滑切换到 OSS URL