大家好,我是陈景序,今天来跟大家聊聊如何用TypeScript封装axios,让我们的Web开发更加高效和规范。
一、定义类型
首先,我们需要定义一些类型,以便更好地管理axios的配置和响应。
// type.ts
import type { AxiosRequestConfig } from 'axios'
export interface httpRequestConfig extends AxiosRequestConfig {
baseURL?: string
headers?: any
timeout?: number
apiType?: string
json?: boolean
form?: [boolean, string]
formUpload?: [boolean, string]
}
// 定义通用响应结构
export interface ApiResponse {
code: number
data: T
message: string
}
二、创建axios实例
接下来,我们创建一个axios实例,并添加一些基础配置和拦截器。
// http.ts
import axios, {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
AxiosError
} from 'axios'
import { httpRequestConfig, ApiResponse } from './types'
import { showToast } from 'vant'
import { API as configApi } from '@/conf/index'
import { userCommonStoreHook } from '@/stores/modules/common'
import * as qs from 'querystring'
// 获取接口根路径
const isProd = import.meta.env.MODE === 'production'
const BASE_PATH: any = isProd ? configApi.production : configApi.development
// 导出Request类,可以用来自定义传递配置来创建实例
export class Request {
// axios 实例
public instance: AxiosInstance
// 基础配置
private baseConfig: httpRequestConfig = {
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json; charset=UTF-8'
},
timeout: 1000 * 60 // 设置超时时间
}
constructor(options: httpRequestConfig) {
this.instance = axios.create(Object.assign(this.baseConfig, options))
this.instance.interceptors.request.use(
(options: httpRequestConfig) => {
// 简化类型设置
const headers = (options.headers = options.headers || {})
if (options.form) {
headers['Content-Type'] =
'application/x-www-form-urlencoded; charset=UTF-8'
delete options.form
}
if (options.formUpload) {
headers['Content-Type'] = 'multipart/form-data; charset=UTF-8'
delete options.formUpload
}
// 校验post数据格式
const contentType = headers['Content-Type']
if (
typeof options.data === 'object' &&
contentType &&
String(contentType).indexOf('application/x-www-form-urlencoded') > -1
) {
options.data = qs.stringify(options.data)
}
let url: any = options.url
let ajaxPath = BASE_PATH[options.apiType || 'defaultAjaxPath']
if (ajaxPath && !url.startsWith('http') && !url.startsWith('https')) {
options.url = ajaxPath + url
}
return options
},
(error: AxiosError) => {
return Promise.reject(error)
}
)
this.instance.interceptors.response.use(
(response: AxiosResponse) => {
return response.data
},
(error: any) => {
if (error.response) {
const data = error.response.data
const status = error.response.status
let errMessage = data.message || '服务忙,请稍后重试(error)'
// ...(省略错误处理代码)
} else {
// ...(省略错误处理代码)
}
return Promise.reject(error)
}
)
}
// 定义请求方法
public request(config: AxiosRequestConfig): Promise {
return this.instance.request(config)
}
public get(config?: AxiosRequestConfig): Promise>> {
return this.instance.get(config?.url as string, config)
}
public post(config?: AxiosRequestConfig): Promise>> {
return this.instance.post(config?.url as string, config?.data, config)
}
public put(config?: AxiosRequestConfig): Promise>> {
return this.instance.put(config?.url as string, config?.data, config)
}
public delete(config?: AxiosRequestConfig): Promise>> {
return this.instance.delete(config?.url as string, config)
}
}
// 默认导出Request实例
export default new Request({})
三、环境配置
最后,我们需要配置环境信息,以便在不同的环境下使用不同的API路径。
/*
* @Desc : 环境配置信息
* @Autor : ZYH
* @Date : 2023-08-17 16:45:28
* @LastEditors : ZYH
* @LastEditTime : 2023-08-17 16:47:58
*/
export const API = {
// 开发环境
development: {
DEFAULT: import.meta.env.BASE_URL,
defaultAjaxPath: '/webspiderweb'
},
// 生产环境
production: {
DEFAULT: import.meta.env.BASE_URL,
defaultAjaxPath: '/webspiderweb'
}
}
const isProd = import.meta.env.MODE === 'production'
export const BASE_CONFIG: AnyObject = isProd ? API.production : API.development
这样,我们就完成了使用TypeScript封装axios的过程。通过封装,我们可以更好地管理API请求,提高代码的可维护性和可读性。
如果你对Web开发有任何疑问,欢迎关注websoft网络软件专家,了解更多精彩内容。
