/config/index.ts:
export const BASE_URL = "http://codercba.com:8000"
export const TIME_OUT = 10000
service/request/type.ts
import type { AxiosRequestConfig, AxiosResponse } from "axios"
// 针对AxiosRequestConfig配置进行扩展
export interface HYInterceptors {
requestSuccessFn?: (config: AxiosRequestConfig) => AxiosRequestConfig
requestFailureFn?: (err: any) => any
responseSuccessFn?: (res: T) => T
responseFailureFn?: (err: any) => any
}
export interface HYRequestConfig extends AxiosRequestConfig {
interceptors?: HYInterceptors
}
service/request/index.ts
import axios from "axios"
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios"
import type { HYRequestConfig } from "./type"
// 拦截器: 蒙版Loading/token/修改配置
/**
* 两个难点:
* 1.拦截器进行精细控制
* > 全局拦截器
* > 实例拦截器
* > 单次请求拦截器
*
* 2.响应结果的类型处理(泛型)
*/
class HYRequest {
//返回的类型
instance: AxiosInstance
// request实例对应 => axios的实例
constructor(config: HYRequestConfig) {
this.instance = axios.create(config)
// 每个instance实例都添加拦截器,全局拦截器
this.instance.interceptors.request.use(config => {
// loading/token
console.log("全局请求成功的拦截")
return config
}, err => {
console.log("全局请求失败的拦截")
return err
})
this.instance.interceptors.response.use(res => {
console.log("全局响应成功的拦截")
return res.data
}, err => {
console.log("全局响应失败的拦截")
return err
})
// 针对特定的hyRequest实例添加拦截器
this.instance.interceptors.request.use(
config.interceptors?.requestSuccessFn,
config.interceptors?.requestFailureFn
)
this.instance.interceptors.response.use(
config.interceptors?.responseSuccessFn,
config.interceptors?.responseFailureFn
)
}
// 封装网络请求的方法
// T => IHomeData
request(config: HYRequestConfig) {
// 单次请求的成功拦截处理
if (config.interceptors?.requestSuccessFn) {
config = config.interceptors.requestSuccessFn(config)
}
// 返回Promise
return new Promise((resolve, reject) => {
this.instance.request(config).then(res => {
// 单次响应的成功拦截处理
if (config.interceptors?.responseSuccessFn) {
res = config.interceptors.responseSuccessFn(res)
}
resolve(res)
}).catch(err => {
reject(err)
})
})
}
get(config: HYRequestConfig) {
return this.request({ ...config, method: "GET" })
}
post(config: HYRequestConfig) {
return this.request({ ...config, method: "POST" })
}
delete(config: HYRequestConfig) {
return this.request({ ...config, method: "DELETE" })
}
patch(config: HYRequestConfig) {
return this.request({ ...config, method: "PATCH" })
}
}
export default HYRequest
service/index.ts
import { BASE_URL, TIME_OUT } from "./config";
import HYRequest from "./request";
const hyRequest = new HYRequest({
baseURL: BASE_URL,
timeout: TIME_OUT
})
export const hyRequest2 = new HYRequest({
baseURL: "http://codercba.com:1888/airbnb/api",
timeout: 8000,
//自定义局部拦截器
interceptors: {
requestSuccessFn: (config) => {
console.log("爱彼迎的请求成功的拦截")
return config
},
requestFailureFn: (err) => {
console.log("爱彼迎的请求失败的拦截")
return err
},
responseSuccessFn: (res) => {
console.log("爱彼迎的响应成功的拦截")
return res
},
responseFailureFn: (err) => {
console.log("爱彼迎的响应失败的拦截")
return err
}
}
})
export default hyRequest
modules/entire.ts
import { hyRequest2 } from "..";
//爱彼迎拦截
hyRequest2.request({
url: "/entire/list",
params: {
offset: 0,
size: 20
}
}).then(res => {
console.log(res)
})
interface IHighScoreData {
list: any[],
subtitle: string,
title: string
type: string,
_id: string
}
//单次拦截
hyRequest2.request({
url: "/home/highscore",
interceptors: {
requestSuccessFn: (config) => {
console.log("/home/highscore请求成功的拦截")
return config
},
responseSuccessFn: (res) => {
console.log("/home/highscore响应成功的拦截")
return res
}
}
}).then(res => {
console.log(res.list, res.subtitle, res.title)
})
modules/home
import hyRequest from "..";
// 发送网络请求
// hyRequest.post
//这个默认全局拦截
interface IHomeData {
data: any,
returnCode: string,
success: boolean
}
hyRequest.request({
url: "/home/multidata"
}).then(res => {
console.log(res.data, res.success, res.returnCode)
})
src/index.ts
import "./service/modules/home"
import "./service/modules/entire"
// webpack依赖图