本文中的实例,是神舟记账项目的。
axios 封装请求
封装要做的事:
- 鉴于axios封装并不好用,考虑使用中间层,即用
HttpClient的类对axios进行封装,好处是可以修改参数,因为axios的参数都是固定的,同时也方便维护; - 做统一的错误处理。(发送频繁429或其他的状态码)
- 加载中
- 新建
http.tsx封装axios和拦截:
// src/shared/Http.tsx
// 先声明类,定义增删改查操作CRUD,再声明函数
import axios, {AxiosInstance} from "axios";
export class Http{
instance:AxiosInstance // 引入 Axios 实例
constructor(baseURL:string){ // 构造函数,传基础参数
this.instance = axios.create({baseURL})
}
get(){} // read
post(){} // create
patch(){} // update
delete(){} // destroy
}
export const http = new Http()
填充具体内容:
import axios, {AxiosInstance} from "axios";
export class Http{
instance:AxiosInstance // 引入 Axios 实例
constructor(baseURL:string){ // 构造函数,传基础参数
this.instance = axios.create({baseURL}) // 初始化
}
// get 接受一个泛型,用来表示返回值的类型,其余的方法区别在于 method
// get 的第 2 个形参为 query 类型是对象 Record ,其中key为string,value为JSONValue
get<R = unknown>(url: string, query?: Record<string, JSONValue>, config?: GetConfig){
return this.instance.request<R>({...config, url: url, params: query, method: "get"});
}
post(){} // create
patch(){} // update
delete(){} // destroy
}
封装统一的拦截
export const http = new Http('/api/v1')
http.instance.interceptors.request.use(config => {}, ()=>{})
http.instance.interceptors.response.use(config => {}, ()=>{})
在业务界面使用封装的Http
// SignInPage.tsx
const onClickSendValidationCode = async () => {
const response = await http.post('/api/v1/validation_codes', { email: formData.email })
.catch(()=>{})
refValidationCode.value.startCount()
}
axios拦截器的使用
用户在点击发送验证码后,短时间内再次点击按钮,就要拦截这次频繁操作的请求,否则就会错乱
axios作弊表,里面有详细的用法
http.instance.interceptors.response.use(response => {
console.log('response')
}, (error)=>{
console.log('error') // error 的类型有很多
if(error.response){
const axiosError = error as AxiosError
if(axiosError.response?.status === 429){
alert('请求太频繁了')
}
}
throw error
})
具体的业务错误,放在业务中条件判断;共有的错误放在http或拦截器里面条件判断,比如频繁点击