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>