useDownloadWithProgress
带进度监控的文件下载 composable,支持实时进度和取消下载。
Usage
使用自动导入的 useDownloadWithProgress composable 进行文件下载,基于原生 fetch 和 ReadableStream 实现,支持实时进度监控和取消下载。
<script setup lang="ts">
// 获取下载相关方法和状态
const { progress, downloading, download, abort } = useDownloadWithProgress()
// 下载文件
const handleDownload = async () => {
await download('/api/export/report', {
filename: 'monthly-report.pdf',
onSuccess: (filename) => {
console.log('下载成功:', filename)
}
})
}
// 取消下载
const handleCancel = () => {
abort()
}
</script>
<template>
<div>
<UButton @click="handleDownload" :loading="downloading">
下载报告
</UButton>
<div v-if="downloading" class="mt-4">
<UProgress :model-value="progress" :max="100"/>
<p>下载中: {{ progress }}%</p>
<UButton color="red" @click="handleCancel">取消</UButton>
</div>
</div>
</template>
useDownloadWithProgress基于原生 API 实现,不依赖第三方库。- 支持自动认证(从 session 获取 token)。
- 自动提取文件名(从响应头或 URL)。
- 内置 Toast 提示。
适用于需要展示下载进度的场景,如大文件导出、批量下载等。对于无需进度的小文件,可以直接使用
$api.$fetch。文件名提取
useDownloadWithProgress 会自动提取文件名,优先级如下:
- 用户提供的
filename选项 - 响应头
Content-Disposition中的文件名 - URL 最后一部分(fallback)
// 1. 自定义文件名
await download('/api/export', {
filename: 'custom-report.pdf'
})
// 保存为: custom-report.pdf
// 2. 从响应头提取
// 响应头: Content-Disposition: attachment; filename="report-2024.pdf"
await download('/api/export')
// 保存为: report-2024.pdf
// 3. 从 URL 提取
await download('/api/export/monthly-report.pdf')
// 保存为: monthly-report.pdf
进度计算
进度基于响应头的 Content-Length:
// 如果响应包含 Content-Length
// 进度 = (已下载字节 / 总字节) * 100
// 如果响应不包含 Content-Length
// 进度保持为 0,但下载仍然正常进行
某些服务器可能不返回 Content-Length,此时无法计算准确进度,但下载功能不受影响。
取消下载
使用 abort() 方法取消正在进行的下载:
const { downloading, download, abort } = useDownloadWithProgress()
// 开始下载
download('/api/export/large-file.zip')
// 用户点击取消
const handleCancel = () => {
if (downloading.value) {
abort() // 中止下载
}
}
取消下载后:
downloading变为falseprogress重置为0- 不会触发
onError回调 - 不会显示 Toast 提示
认证集成
useDownloadWithProgress 会自动从 session 获取 token 并添加到请求头:
// 自动添加 Authorization 头
await download('/api/export/private-report.pdf')
// 请求头: Authorization: Bearer <token>
如需额外的请求头:
await download('/api/export', {
headers: {
'X-Custom-Header': 'value'
}
})
API
useDownloadWithProgress()
useDownloadWithProgress(): { progress, downloading, error, download, abort }
创建下载管理器。
Returns
返回包含以下方法和属性的下载管理器对象:
progress
Ref<number>
下载进度,范围 0-100。
downloading
Ref<boolean>
是否正在下载中。
error
Ref<Error | null>
错误信息(如果下载失败)。
download()
(url: string, options?: DownloadWithProgressOptions) => Promise<{ success: boolean, error: Error | null }>
执行下载。
Parameters
url
string required
下载文件的 URL。
options
DownloadWithProgressOptions
下载配置选项。
filename
string
自定义文件名。不提供时从响应头的
Content-Disposition 或 URL 中提取。headers
Record<string, string>
额外的请求头。
toast
RequestToastOptions | false
Toast 提示配置。设为
false 禁用 Toast。endpoint
string
使用指定的端点配置。
onSuccess
(filename: string) => void
下载成功回调,接收最终的文件名。
onError
(error: Error) => void
下载失败回调,接收错误对象。
Returns
返回 Promise<{ success: boolean, error: Error | null }>:
success- 下载是否成功error- 错误信息(成功时为null)
abort()
() => void
中止当前下载,重置进度和状态。
Changelog
f2709 — refactor: 重构 API 配置架构并新增上传下载组件