持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情
封装了一个axios的请求方法,同时加了一个缓存防抖,以及请求错误时可以重新请求自动请求接口的方法. 当然,其中存在不完善的地方请见谅
封装代码:
import axios from 'axios'
import qs from 'qs'
// 防抖数据
let requestDou =localStorage.getItem('requestDou')?JSON.parse(localStorage.getItem('requestDou')):[];
// 创建axios实例
const initAxios = (postData,timeout=60000) => {
// 拦截
const AxiosInstance = axios.create({
baseURL: process.env.VUE_APP_BASE_URL,
timeout: timeout,
withCredentials: true,
emulateJSON: true,
})
// 接口发起前
AxiosInstance.interceptors.request.use(config => {
config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
// 不使用config里面的数据,如果做加解密判断,使用qs会改变数据的类型
if(config.method.toUpperCase() === 'GET'){
config.params=postData
}else{
config.data=qs.stringify(postData, { arrayFormat: 'indices'})
}
return config
})
// 接口发起后
AxiosInstance.interceptors.response.use(
// 成功的请求
response => {
if(response.data.status==1){
return Promise.resolve(response.data)
}else{
return Promise.reject(response)
}
},
// 失败的请求
error=>{
let errorMsgTitle=error || '请求失败!'
let errorObjecy={
msg:errorMsgTitle
}
// 页面超时
if(error.code === 'ECONNABORTED' || error.message ==="Network Error" || error.message.includes("timeout")){
errorObjecy.msg='请求超时,请重新刷新页面'
// 返回页面超时
errorObjecy['isTimeout']=true
}
// 抛错
return Promise.reject(errorObjecy)
}
)
return AxiosInstance
}
// 防抖数据缓存处理
function setDouData(data,delIndex=0,number=0){
if(number>0){
requestDou.splice(delIndex,number)
}else{
requestDou.splice(delIndex,number,data)
}
localStorage.setItem('requestDou',JSON.stringify(requestDou))
}
// 清除防抖
function delDouData(data){
setTimeout(()=>{
let index=requestDou.findIndex(n=>n && n.url==data.url && data.data==n.data)
if(index!=-1){
setDouData(data,index,1)
}
},300)
}
// request方法
const requestAxios =(
{
url,
method = 'post',
data={},//参数
timeout=60000,//超时时间,默认60秒
is_anti=true,
}
)=>{
// axios配置
const options = {
url,
method,
params: method.toUpperCase() === 'GET' || method.toUpperCase() === 'DELETE' ? data : null,
data: method.toUpperCase() === 'POST' || method.toUpperCase() === 'PUT' ? data : null,
}
let thisPostTime=new Date().getTime()
let requestDouItem={
url:url,
time:thisPostTime,
data:JSON.stringify(data)
}
// 提交数据
return new Promise((resolve, reject) => {
// 接口防抖判断
if(is_anti){
if(requestDou.findIndex(n=>n && n.url==url && n.data==JSON.stringify(data))!=-1){
reject({
msg:'操作频繁!'
})
return false;
}
}
setDouData(requestDouItem)
const AxiosInstance = initAxios(data,timeout)
AxiosInstance(options).then(res=>{
delDouData(requestDouItem)
if(res){
resolve(res)
}
}).catch(error=>{
delDouData(requestDouItem)
reject(error)
})
})
}
// 导出
export function request(requestParms,reuseData={}){
if(!Object.hasOwnProperty.call(reuseData,'is_reuse')){
reuseData.is_reuse=false
}
if(!Object.hasOwnProperty.call(reuseData,'num')){
reuseData.num=1
}
return new Promise((resolve, reject) => {
requestAxios(requestParms).then(res=>{
resolve(res)
}).catch(error=>{
if(reuseData.is_reuse && reuseData.num>0){
reuseData.num=reuseData.num-1
request(requestParms,reuseData)
}
reject(error)
})
})
}
使用:
import {request} from '@/utils/request'
request({
url:'https://www.baidu.com',
// method:'GET',
data:{
xx:99,
c:88,
}
},{is_reuse:true,num:5}).then(res=>{
console.log(res)
})