useDownloadWithProgress

View source
带进度监控的文件下载 composable,支持实时进度和取消下载。

Usage

使用自动导入的 useDownloadWithProgress composable 进行文件下载,基于原生 fetchReadableStream 实现,支持实时进度监控和取消下载。

<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
了解 API 系统的全局配置选项

文件名提取

useDownloadWithProgress 会自动提取文件名,优先级如下:

  1. 用户提供的 filename 选项
  2. 响应头 Content-Disposition 中的文件名
  3. 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 变为 false
  • progress 重置为 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 }>
执行下载。
abort()
() => void
中止当前下载,重置进度和状态。

Changelog

f2709 — refactor: 重构 API 配置架构并新增上传下载组件

Copyright © 2025 - 2026 YiXuan - MIT License