在日常生活中,有时我们需要从网站下载文件,例如文档、图片、音频、视频等等。然而,传统的下载方式需要用户进入新页面或弹窗进行下载,操作繁琐并且影响用户体验。因此,在这篇文章中,我们将介绍如何使用Vue框架实现一种更加简便、快捷的下载文件功能,提高用户的浏览体验。
一、使用axios实现文件下载
为了实现下载功能,我们需要使用到Vue框架中的网络请求库axios,下载文件的过程在后端实现,前端只需发送请求即可。具体实现过程如下:
import axios from 'axios'
export const downloadFile = function(url, params) {
return new Promise((resolve, reject) => {
axios.post(url, params, {
responseType: 'blob'
})
.then(response => {
// 获取后端返回的文件名
var fileName = response.headers['content-...
// 通过浏览器下载文件
var url = window.URL.createObjectURL(new Blob([res...))
var link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
resolve()
})
.catch(error => {
reject(error)
})
})
}
在代码中,我们定义了一个名为downloadFile的函数,它接收两个参数,url表示文件下载链接,params为下载参数,我们可以在params参数中配置一些可选项,例如请求头、请求体等信息,这里不再赘述。在函数内部,我们先发送一个post请求,并且设置响应数据类型为blob(二进制流),这样返回的数据就可以直接用于下载文件了。后端需要设置Content-Disposition响应头信息,告诉浏览器要下载文件。我们可以在响应头中自定义文件名,然后通过Blob对象创建一个URL链接,将链接赋值给一个隐藏的标签,并指定下载文件的文件名,最后调用click()方法触发下载即可。如果需要异步调用downloadFile函数,可以通过Promise进行封装。
二、使用Vue组件方式封装下载组件
既然下载文件是常见的需求,那么我们可以将下载功能封装为一个Vue组件,方便在项目中重复使用。我们来实现一个DownloadButton组件,它可以接收两个属性:URL和params,分别表示文件下载链接和请求参数。
<template>
<button @click="handleDownload">下载</button>
</template>
<script>
import axios from 'axios'
export default {
name: 'DownloadButton',
props: {
url: String,
params: Object
},
methods: {
handleDownload() {
axios.post(this.url, this.params, {
responseType: 'blob'
}).then(response => {
...
}).catch(error => {
console.log(error)
})
}
}
}
</script>
在代码中,我们首先引入了axios库,并在组件定义中声明了name属性以及props属性,接着定义了一个名为handleDownload的函数,用于处理下载逻辑。当用户点击下载按钮时,我们调用axios库发送post请求,并将响应数据类型设置为blob(二进制流),在请求成功后,执行和上文一样的下载逻辑即可。此时,我们已经将下载功能封装成了一个完整的组件,可以在任意页面使用只需传入相应的URL和params参数即可。
三、使用Element UI提示下载进度
通常情况下,我们在下载文件时可能需要等待一段时间,这段时间可能很短,也可能很长,用户无从得知。为了提高用户体验,我们可以使用Element UI框架提供的Progress组件,在下载文件时显示下载进度,从而让用户感受到下载的进展。
<template>
<div>
<el-button type="primary" :loading="loading" @click="startDownload">下载文件</el-button>
<el-progress v-if="downloading" :percentage="downloadProgress" show-text strokeLinecap="square" />
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'DownloadProgress',
data() {
return {
loading: false,
downloading: false,
downloadProgress: 0,
downloadUrl: '',
downloadParams: {}
}
},
methods: {
startDownload() {
this.loading = true
axios.post(this.downloadUrl, this.downloadParams, {
responseType: 'blob',
onDownloadProgress: progressEvent => {
// 更新下载进度
this.downloadProgress = Math.floor(progressEvent.loaded / progressEvent.total * 100)
}
}).then(response => {
...
}).catch(error => {
console.log(error)
})
}
},
props: {
url: String,
params: Object
},
watch: {
url(val) {
this.downloadUrl = val
},
params(val) {
this.downloadParams = val
}
}
}
</script>
在代码中,我们首先在组件定义中声明了data属性,包含了4个属性:loading表示按钮是否处于loading状态,downloading表示是否正在下载文件,downloadProgress表示下载进度,downloadUrl和downloadParams分别表示文件下载链接和请求参数。在模板中,我们使用了Element UI的Button组件,绑定了一个startDownload方法,在方法内调用了axios库发送post请求,并设置响应数据类型为blob(二进制流),同时指定了onDownloadProgress回调函数,在下载过程中可以将下载进度更新给downloadProgress属性。在下载结束后,执行和上文一样的下载逻辑即可。最后,我们在模板中使用了Element UI的Progress组件,根据downloadProgress动态展示下载进度。通过此种方式,我们可以实现一个带有下载进度提示的下载组件。