- utils/axios/type/axios.ts
export type ErrorMessageMode = "none" | "modal" | "message" | undefined; export interface RequestOptions { // Splicing request parameters to url joinParamsToUrl?: boolean; // Format request parameter time formatDate?: boolean; // Whether to process the request result isTransformResponse?: boolean; // Whether to return native response headers // For example: use this attribute when you need to get the response headers isReturnNativeResponse?: boolean; // Whether to join url joinPrefix?: boolean; // Interface address, use the default apiUrl if you leave it blank apiUrl?: string; // 请求拼接路径 urlPrefix?: string; // Error message prompt type errorMessageMode?: ErrorMessageMode; // Whether to add a timestamp joinTime?: boolean; ignoreCancelToken?: boolean; // Whether to send token in header withToken?: boolean; } export interface Result<T = unknown> { code: number; type: "success" | "error" | "warning"; message: string; result: T; } // multipart/form-data: upload file export interface UploadFileParams { // Other parameters data?: any; // File parameter interface field name name?: string; // file name file: File | Blob; // file name filename?: string; [key: string]: any; }
- utils/axios/config.ts
import type { AxiosRequestConfig } from "axios"; import type { RequestOptions } from "./types/axios"; export interface CreateAxiosOptions extends AxiosRequestConfig { requestOptions?: RequestOptions; } export function DefaultAxiosConfig(): CreateAxiosOptions { return { baseURL: "/api", headers: { "Content-Type": "application/json;charset=UTF-8", "Access-Control-Allow-Origin-Type": "*", }, timeout: 30000, withCredentials: true, validateStatus() { return true; }, requestOptions: { isTransformResponse: true, }, }; }
-
utils/axios/index.ts
import { FrogAxios } from "./frog-axios"; import { DefaultAxiosConfig } from "./config"; function createFrogAxios() { return new FrogAxios(DefaultAxiosConfig()); } export const defHttp = createFrogAxios();
-
utils/axios/frog-axios.ts
import axios, { type InternalAxiosRequestConfig } from "axios"; import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError, } from "axios"; import type { CreateAxiosOptions } from "./config"; import type { RequestOptions, Result } from "./types/axios"; import { errorHandle } from "./errorHandle"; export class FrogAxios { private axiosInstance: AxiosInstance; private readonly options: CreateAxiosOptions; constructor(options: CreateAxiosOptions) { this.options = options; this.axiosInstance = axios.create(options); this.setupInterceptors(); } private setupInterceptors() { /** * 请求拦截器 * 每次请求前,如果存在token则在请求头中携带token */ this.axiosInstance.interceptors.request.use( (config:InternalAxiosRequestConfig<any>) => { config.data = JSON.stringify(config.data); return config; }, (error) => { return Promise.reject(error); } ); this.axiosInstance.interceptors.response.use( (response:AxiosResponse<any, any>) => { if (response.status === 200) { return response; } else { errorHandle(response.status); console.log(response); return response; } }, (error) => { if (!navigator.onLine) { console.log("网络不可用,请链接网络"); // message.error('网络不可用,请链接网络'); } } ); } post<T = unknown>( config: AxiosRequestConfig, options?: RequestOptions ): Promise<T> { return this.request({ ...config, method: "POST" }, options); } get<T = unknown>( config: AxiosRequestConfig, options?: RequestOptions ): Promise<T> { return this.request({ ...config, method: "GET" }, options); } request<T = unknown>( config: AxiosRequestConfig, options?: RequestOptions ): Promise<T> { const conf: CreateAxiosOptions = config; const { requestOptions } = this.options; const opt: RequestOptions = Object.assign({}, requestOptions, options); conf.requestOptions = opt; return new Promise((resolve, reject) => { this.axiosInstance .request<unknown, AxiosResponse<Result>>(conf) .then((res: AxiosResponse<Result>) => { resolve(res as unknown as Promise<T>); }) .catch((e: Error | AxiosError) => { reject(e); }); }); } }
-
utils/axios/errorHandle.ts
// import { message } from 'antd'; export const errorHandle = (status: number) => { // 状态码判断 switch (status) { case 400: console.log(status); // message.warning('发出的请求有错误,服务器没有进行新建或修改数据的操作==>' + status); break; case 401: // 重定向 console.log(status); // message.warning('token:登录失效==>' + status); break; case 404: console.log(status); // message.warning('网络请求不存在==>' + status); break; case 410: console.log(status); // message.warning('请求的资源被永久删除,且不会再得到的==>' + status); break; case 500: console.log("500"); // message.error('服务器发生错误,请检查服务器==>' + status); break; case 502: console.log(status); // message.error('网关错误==>' + status); break; case 503: console.log(status); // message.error('服务不可用,服务器暂时过载或维护==>' + status); break; case 504: console.log(status); // message.error('网关超时==>' + status); break; default: console.log(status); // message.error('其他错误错误==>' + status); } };
-
services/index.ts
import { defHttp } from "@/utils/axios"; import type { RootObject } from "./type"; export async function handleList() { return await defHttp.get<RootObject>({ url: "/v2/index_entry" }); }
-
services/type.ts
/* * @Description: * @Date: 2023-04-25 22:54:12 * @Author: grab * @Copyright: (c) 2018-2022 宁波哥爱帮科技有限公司 */ export interface RootObject { data: Datum[]; status: number; statusText: string; headers: Headers; config: Config; request: Env; } interface Config { transitional: Transitional; adapter: string[]; transformRequest: null[]; transformResponse: null[]; timeout: number; xsrfCookieName: string; xsrfHeaderName: string; maxContentLength: number; maxBodyLength: number; env: Env; headers: Headers2; baseURL: string; withCredentials: boolean; method: string; url: string; } interface Headers2 { Accept: string; 'Access-Control-Allow-Origin-Type': string; } interface Env { } interface Transitional { silentJSONParsing: boolean; forcedJSONParsing: boolean; clarifyTimeoutError: boolean; } interface Headers { 'access-control-allow-credentials': string; 'access-control-allow-headers': string; 'access-control-allow-methods': string; 'access-control-allow-origin': string; 'content-encoding': string; 'content-type': string; date: string; etag: string; server: string; vary: string; 'x-powered-by': string; } interface Datum { id: number; is_in_serving: boolean; description: string; title: string; link: string; image_url: string; icon_url: string; title_color: string; __v: number; }
-
使用
<template> <view class="content"> <view @click="get()">网络请求点击事件测试</view> </view> </template> <script lang="ts"> import type { RootObject } from "@/services/type"; import { defineComponent } from "vue"; import { handleList} from "../../services/index"; export default defineComponent({ setup() { function get() { handleList().then((res:RootObject) => { console.log(res.data); }); } return { get, }; }, }); </script> <style> </style> function get() { throw new Error('Function not implemented.'); }