您的位置:

Vue实现下载文件功能,提高网站用户体验

在日常生活中,有时我们需要从网站下载文件,例如文档、图片、音频、视频等等。然而,传统的下载方式需要用户进入新页面或弹窗进行下载,操作繁琐并且影响用户体验。因此,在这篇文章中,我们将介绍如何使用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动态展示下载进度。通过此种方式,我们可以实现一个带有下载进度提示的下载组件。