vue实现下载组件
Vue 实现下载组件的几种方法
使用 <a> 标签下载
在 Vue 中可以直接使用 <a> 标签的 download 属性实现文件下载。适用于已知文件 URL 的情况。
<template>
<a :href="fileUrl" download>点击下载文件</a>
</template>
<script>
export default {
data() {
return {
fileUrl: 'https://example.com/path/to/file.pdf'
}
}
}
</script>
通过 Blob 对象下载
当需要从后端 API 获取文件数据时,可以使用 Blob 对象处理二进制数据。

<template>
<button @click="downloadFile">下载文件</button>
</template>
<script>
export default {
methods: {
async downloadFile() {
const response = await fetch('https://api.example.com/download')
const blob = await response.blob()
const url = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'filename.ext'
document.body.appendChild(a)
a.click()
window.URL.revokeObjectURL(url)
document.body.removeChild(a)
}
}
}
</script>
使用 axios 下载文件
使用 axios 处理文件下载请求时,需要设置 responseType: 'blob'。

<template>
<button @click="downloadWithAxios">使用axios下载</button>
</template>
<script>
import axios from 'axios'
export default {
methods: {
async downloadWithAxios() {
try {
const response = await axios.get('https://api.example.com/download', {
responseType: 'blob'
})
const url = window.URL.createObjectURL(new Blob([response.data]))
const link = document.createElement('a')
link.href = url
link.setAttribute('download', 'file.ext')
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
} catch (error) {
console.error('下载失败:', error)
}
}
}
}
</script>
封装可复用的下载组件
可以创建一个可复用的下载组件,接收文件 URL 和文件名作为 props。
<template>
<button @click="handleDownload" :disabled="isDownloading">
{{ isDownloading ? '下载中...' : '下载文件' }}
</button>
</template>
<script>
export default {
props: {
fileUrl: {
type: String,
required: true
},
fileName: {
type: String,
default: 'download'
}
},
data() {
return {
isDownloading: false
}
},
methods: {
async handleDownload() {
this.isDownloading = true
try {
const response = await fetch(this.fileUrl)
const blob = await response.blob()
const url = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = this.fileName
document.body.appendChild(a)
a.click()
window.URL.revokeObjectURL(url)
document.body.removeChild(a)
} catch (error) {
console.error('下载失败:', error)
} finally {
this.isDownloading = false
}
}
}
}
</script>
处理大文件下载进度
对于大文件下载,可以显示下载进度条。
<template>
<div>
<button @click="downloadLargeFile">下载大文件</button>
<progress v-if="progress > 0" :value="progress" max="100"></progress>
</div>
</template>
<script>
export default {
data() {
return {
progress: 0
}
},
methods: {
async downloadLargeFile() {
try {
const response = await fetch('https://example.com/large-file', {
signal: AbortSignal.timeout(30000)
})
if (!response.ok) throw new Error('下载失败')
const reader = response.body.getReader()
const contentLength = +response.headers.get('Content-Length')
let receivedLength = 0
let chunks = []
while(true) {
const {done, value} = await reader.read()
if (done) break
chunks.push(value)
receivedLength += value.length
this.progress = Math.round((receivedLength / contentLength) * 100)
}
const blob = new Blob(chunks)
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'large-file.ext'
document.body.appendChild(a)
a.click()
URL.revokeObjectURL(url)
document.body.removeChild(a)
} catch (error) {
console.error('下载错误:', error)
} finally {
this.progress = 0
}
}
}
}
</script>
这些方法覆盖了 Vue 中实现文件下载的常见场景,包括简单下载、API 数据下载、大文件下载和组件封装。根据具体需求选择适合的实现方式。






