vue通过接口下载文件的封装及使用

1、先封装axios请求(request.js)

import axios from 'axios'
import { Message, Loading } from 'element-ui'
import Vue from 'vue'
axios.defaults.withCredentials = true
let loading = null // 定义loading变量
const startLoading = () => {
  loading = Loading.service({
    lock: true,
    text: '正在玩命加载中……',
    background: 'rgba(0, 0, 0, 0.7)'
  })
}
// 结束 取消loading加载
const endLoading = () => {
  loading.close()
}

let needLoadingRequestCount = 0 // 声明一个变量

const showFullScreenLoading = () => {
  if (needLoadingRequestCount === 0) { // 当等于0时证明第一次请求 这时开启loading
    startLoading()
  }
  needLoadingRequestCount++ // 全局变量值++
}

const tryHideFullScreenLoading = () => {
  if (needLoadingRequestCount <= 0) return // 小于等于0 证明没有开启loading 此时return
  needLoadingRequestCount-- // 正常响应后 全局变量 --
  if (needLoadingRequestCount === 0) { // 等于0 时证明全部加载完毕 此时结束loading 加载
    endLoading()
  }
}

// import store from '../store'
Vue.prototype.$message = Message
const service = axios.create({
  // timeout: 50000, // request timeout
  baseURL: process.env.VUE_APP_BASE_API,
  withCredentials: true,
  crossDomain: true
})
// request interceptor
service.interceptors.request.use(
  config => {
    config.headers.Authorization = window.localStorage.getItem('token')
    config.headers.platform = window.sessionStorage.getItem('platform')
    showFullScreenLoading()
    return config
  },
  error => {
    Promise.reject(error)
  }
)
service.interceptors.response.use(
  response => {
    const res = response.data
    if (res.code) {
      if (res.code == 1000) {
        tryHideFullScreenLoading()
        return Promise.resolve(res)
      } else if (res.code == 1002) {
        window.sessionStorage.clear()
        Vue.prototype.$message('请登录')
        tryHideFullScreenLoading()
        return Promise.reject(res)
      } else {
        Vue.prototype.$message.warning(res.msg)
        tryHideFullScreenLoading()
        return Promise.reject(res)
      }
    } else {
      tryHideFullScreenLoading()
      return Promise.resolve(response)
    }
  }, error => {
    tryHideFullScreenLoading()
    Vue.prototype.$message(error + '请求超时')
  })

export default service

2、在针对接口返回的数据流进行2次封装(http.js)

import request from '../utils/request'
import { Toast } from 'vant'
let loading = null // 定义loading变量
const fileExport = (url, fileName, params) => {
  loading = Toast.loading({
    message: '加载中...',
    forbidClick: true,
    duration: 0
  })
  return request.post(url, params, {
    responseType: 'blob',
    isBlobRequest: true
  }).then(res => {
    // console.log(res, 'res')
    // 设置responseType: 'blob',导致返回数据是Blob类型数据,需要转回JSON格式,展示接口请求失败返回的msg信息
    // 创建一个 FileReader 对象
    const reader = new FileReader()
    // 设置当读取完成时的回调函数
    reader.onload = function (event) {
      try {
        // 尝试解析 JSON 数据
        const jsonData = JSON.parse(event.target.result)
        Toast.fail(jsonData.msg)
        // console.log('JSON 数据解析成功:', jsonData)
        // 此处可以进行成功后的操作
      } catch (error) {
        const blob = new Blob([res.data])
        if ('download' in document.createElement('a')) { // 非IE下载
          const elink = document.createElement('a')
          if (fileName) {
            elink.download = fileName
          } else {
            const fileNameEdit = res.headers['content-disposition']
            // console.log(fileNameEdit, 'fileNameEdit')
            const extractedFileName = fileNameEdit.match(/filename="([^"]+)"/)[1]
            elink.download = extractedFileName
          }
          elink.style.display = 'none'
          elink.href = URL.createObjectURL(blob)
          document.body.appendChild(elink)
          elink.click()
          URL.revokeObjectURL(elink.href) // 释放URL 对象
          document.body.removeChild(elink)
        } else { // IE10+下载
          navigator.msSaveBlob(blob, fileName)
        }
        loading.close()
        // console.log('JSON 数据解析失败:', error)
        // 此处可以进行解析失败后的操作
      }
    }
    // 开始读取 Blob 数据
    reader.readAsText(res.data)
  }).catch(e => {
    console.error(e)
  })
}

export { fileExport }


3、api接口文件(material.js)

import { fileExport } from '../utils/http'
// 资料包打包下载
export const materialCompress = (fileName, params) => {
  fileExport('/material/compress', fileName, params)
}

4、在界面中使用

<template>
	<div>
	...
	<div class="packageDownload">
      <van-button type="info" size="large" @click="packageDownload">打包下载</van-button>
    </div>
	</div>
</template>

<script>
import {materialCompress} from '../api/material'
export default {
	...
	methods: {
	    packageDownload () {
	      let name = '文件名称'+'.文件格式'
	      materialCompress(name, {
	        material_id: this.material_id
	      })
	    }
	}
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3 中接口请求的封装有多种方式,下面我会介绍一种常见的方法: 首先,我们可以创建一个独立的模块,专门用于发送接口请求。这个模块可以是一个单独的文件,比如 `api.js`。 ```javascript import axios from 'axios'; const api = axios.create({ baseURL: 'http://api.example.com', // 接口请求的基础 URL timeout: 5000, // 请求超时时间 }); export function fetchUser(userId) { return api.get(`/user/${userId}`); } export function updateUser(userId, data) { return api.put(`/user/${userId}`, data); } // 其他接口请求方法... ``` 然后,在需要使用接口的地方,我们可以导入上面定义的方法,并调用它们来发送请求。 ```javascript import { fetchUser, updateUser } from './api'; export default { data() { return { user: null, }; }, methods: { async getUser(userId) { try { const response = await fetchUser(userId); this.user = response.data; } catch (error) { console.error(error); } }, async updateUser(userId, data) { try { await updateUser(userId, data); // 更新成功的处理逻辑... } catch (error) { console.error(error); } }, // 其他接口请求方法... }, }; ``` 上述代码中,我们使用了 axios 库来发送实际的请求。你可以根据项目需求选择其他库或自己封装一个请求库。 需要注意的是,上述代码只是一个简单的示例,实际项目中可能还需要处理请求的错误、loading 状态、请求拦截器、响应拦截器等等。具体的封装方式可以根据项目的需求进行调整和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值