组件创建一个ref属性,控制局部的loading状态,将这个属性传入axios实例中,在请求开始的时候,设置为true,请求结束后,设置为false。
// index.ts
import axios, {AxiosRequestConfig} from "axios"
import {useUserInfo} from "../store/moduls/userinfo"; // 用户登录信息的pinia
import {Ref} from "vue"; // ref的类型
import {useLayout} from "../store/moduls/layout"; // 全局loading的pinia
interface loadingtype {
[prop: string]: Ref
}
const loadingstorage: loadingtype = {} // 所有加载状态的仓库,key是url,value是ref数据,保证这边修改,那边同步修改
const excepturl:Array = [] // 不需要防抖的url数组
let antiShakeurlList:Array = [] // 被缓存的url数组
const BaseUrl = import.meta.env.VITE_RES_URL || "/proxy/"
const http = axios.create({
// 联调
// baseURL: process.env.NODE_ENV === 'mock' ? `/api/` : '/proxy/',
baseURL: BaseUrl,
// 是否跨站点访问控制请求
withCredentials: false,
// 返回树状数据大约需要5-6秒,设置最大超时为10秒
timeout: 10000,
// 请求数据拦截
// transformRequest: [
// (data) => {
// return data
// },
// ],
validateStatus() {
// 使用async-await,处理reject情况较为繁琐,所以全部返回resolve,在业务代码中处理异常
return true
},
// 响应数据拦截
transformResponse: [
(data) => {
if (typeof data === 'string' && data.startsWith('{') || data.startsWith('[')) {
data = JSON.parse(data)
}
return data
},
],
});
// 请求拦截器
http.interceptors.request.use(
(config: AxiosRequestConfig) => {
// 使用秘钥加密数据,暂时不做
// 添加token
const userInfo = useUserInfo()
if (userInfo.token) {
// @ts-ignore
config.headers['Authorization'] = "www+" + userInfo.token
}
return config
},
)
const request = (method: "post" | "get" | "put" | "delete", url: string, data: any = null, params: any = null, headers: any = null, loading: null | Ref) => {
// 判断是否是不防抖的url
if(!excepturl.includes(url)){
// 判断是否已经发起请求
if(antiShakeurlList.includes(url)){
return Promise.reject("别点这么快,想死啊!")
}else{
// 将现在的url放入缓存列表
antiShakeurlList.push(url)
}
}
const loadingkey: string = url + new Date().getTime()
// 如果没有传入局部loading,就打开全局loading遮罩
if (loading != null) {
console.log("自定义的loading")
loading.value = true;
loadingstorage[loadingkey] = loading
}else{
console.log("全局的loading")
const mylayout = useLayout()
mylayout.changezhezhao(true)
}
return new Promise((resolve, reject) => {
http({method: method, url: url, data: data, params: params,headers:headers}).then(res => {
// 请求成功,删除缓存的url
antiShakeurlList = antiShakeurlList.filter(item=>item!==url)
// 关闭loading
if(loadingstorage[loadingkey]){
loadingstorage[loadingkey].value = false
delete loadingstorage[loadingkey]
}else{
const mylayout = useLayout()
mylayout.changezhezhao(false)
}
resolve(res)
}).catch((error: Error) => {
// 请求失败,删除缓存的url
antiShakeurlList = antiShakeurlList.filter(item=>item!==url)
// 关闭loading
if(loadingstorage[loadingkey]){
loadingstorage[loadingkey].value = false
delete loadingstorage[loadingkey]
}else{
const mylayout = useLayout()
mylayout.changezhezhao(false)
}
console.log(error,"都有什么东西")
if(error.message.search("timeout")){
reject("请求超时")
}else{
reject(error.message)
}
})
})
}
// 创建方法
export function json(url: string, data:any = null, loading: null | Ref = null) {
return request(
"post",
url,
data,
null,
{'Content-Type': 'application/json;charset=utf-8',},
loading,
)
}
// 更新方法
export function update(url: string, data: any = null, id: string | null = null, loading: null | Ref = null) {
if (id) {
return request(
"put",
url + id + "/",
data,
null,
{'Content-Type': 'application/json;charset=utf-8',},
loading,
)
} else {
return request(
"put",
url,
data,
null,
{'Content-Type': 'application/json;charset=utf-8',},
loading,
)
}
}
// 删除方法
export function shanchu(url: string, data:any = null, id:string|null = null, loading: null | Ref = null) {
if (id) {
return request(
"delete",
url + id + "/",
null,
data,
{'Content-Type': 'application/json;charset=utf-8',},
loading,
)
} else {
return request(
"delete",
url,
null,
data,
{'Content-Type': 'application/json;charset=utf-8',},
loading,
)
}
}
// 单查方法
export function get(url: string, data:any = null, id:null|string = null, loading: null | Ref =null) {
if (id) {
return request(
"get",
url + id + "/",
null,
data,
{'Content-Type': 'application/json;charset=utf-8',},
loading,
)
} else {
return request(
"get",
url,
null,
data,
{'Content-Type': 'application/json;charset=utf-8',},
loading,
)
}
}
// 群查方法
export function list(url: string, data:any = null, loading: null | Ref = null) {
return request(
"get",
url,
null,
data,
{'Content-Type': 'application/json;charset=utf-8',},
loading,
)
}
// 表单创建方法
export function form(url: string, data:any = null, loading: null | Ref = null) {
return request(
"post",
url,
data,
null,
{'Content-Type': 'application/x-www-form-urlencoded'},
// transformRequest: [function (data) {
// let ret = ''
// for (const it in data) {
// ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
// }
// return ret
// }]
loading,
)
}
menulist: (data: any,loading:Ref|null=null) => list(api.menu, data,loading), // 菜单管理群查
menuget: (data: any, id:any = null,loading:Ref|null=null) => get(api.menu, data, id,loading), // 菜单管理单查
menuadd: (data: any,loading:Ref|null=null) => json(api.menu, data,loading), // 菜单管理增加
menuupdate: (data: any, id:any = null,loading:Ref|null=null) => update(api.menu, data, id,loading), // 菜单管理修改
menudelete: (data: any, id:any = null,loading:Ref|null=null) => shanchu(api.menu, data, id,loading), // 菜单管理删除
menufilter: (data: any, id:any = null,loading:Ref|null=null) => get(api.menufilter, data, id,loading), // 菜单管理过滤
menuall: (data: any,loading:Ref|null=null) => list(api.menuall, data,loading), // 获取所有菜单