TS axios封装

news/2025/3/15 10:45:09/

方式一

service/request/request.ts

import axios from 'axios'
import { ElLoading } from 'element-plus'
import type { AxiosRequestConfig, AxiosInstance, AxiosResponse } from 'axios'
import type { ILoadingInstance } from 'element-plus/lib/el-loading/src/loading.type'// import type { LoadingInstance } from "element-plus/lib/components/loading/src/loading"; // 按需引入/*** 封装axios* 这里使用类进行封装是因为类具有更强的一个封装性* 比单纯的用函数去进行封装要更好一些* 使用方式:LWJRequest.get()*/
// 拦截器类型约束--接口
// 可以让不同的类拥有不同的拦截器,更加灵活
interface InterceptorHooks {requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfigrequestInterceptorCatch?: (error: any) => anyresponseInterceptor?: (response: AxiosResponse) => AxiosResponseresponseInterceptorCatch?: (error: any) => any
}// 类接口
interface LWJRequestConfig extends AxiosRequestConfig {showLoading?: booleaninterceptorHooks?: InterceptorHooks
}// 属性接口
interface LWJData<T> {data: TreturnCode: stringsuccess: boolean
}// 封装请求类
class LWJRequest {config: AxiosRequestConfiginterceptorHooks?: InterceptorHooksshowLoading: booleanloading?: ILoadingInstanceinstance: AxiosInstanceconstructor(options: LWJRequestConfig) {this.config = optionsthis.interceptorHooks = options.interceptorHooksthis.showLoading = options.showLoading ?? truethis.instance = axios.create(options)this.setupInterceptor()}// 拦截器函数setupInterceptor(): void {// 请求拦截this.instance.interceptors.request.use(this.interceptorHooks?.requestInterceptor,this.interceptorHooks?.requestInterceptorCatch)// 响应拦截this.instance.interceptors.response.use(this.interceptorHooks?.responseInterceptor,this.interceptorHooks?.responseInterceptorCatch)// 添加所有实例都有的拦截器--请求拦截器this.instance.interceptors.request.use((config) => {if (this.showLoading) {this.loading = ElLoading.service({lock: true,text: 'Loading',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})}return config})// 正在加载效果--响应拦截器this.instance.interceptors.response.use((res) => {// setTimeout(()=>{//   this.loading?.close()// },1000)this.loading?.close()return res},(err) => {this.loading?.close()// if(err.response.status === 404){// }return err})}// 某一个单独的请求拦截器request<T = any>(config: LWJRequestConfig): Promise<T> {if (!config.showLoading) {this.showLoading = false}return new Promise((resolve, reject) => {this.instance.request<any, LWJData<T>>(config).then((res) => {resolve(res.data)this.showLoading = true}).catch((err) => {reject(err)this.showLoading = true})})}// 封装get请求get<T = any>(config: LWJRequestConfig): Promise<T> {return this.request({ ...config, method: 'GET' })}// 封装post请求post<T = any>(config: LWJRequestConfig): Promise<T> {return this.request({ ...config, method: 'POST' })}// 封装delete请求delete<T = any>(config: LWJRequestConfig): Promise<T> {return this.request({ ...config, method: 'DELETE' })}// 封装patch请求patch<T = any>(config: LWJRequestConfig): Promise<T> {return this.request({ ...config, method: 'PATCH' })}
}export default LWJRequest

service/request/config.ts

// 1.区分环境变量方式一:
// export const API_BASE_URL = 'https://coderwhy/org/dev'
// export const API_BASE_URL = 'https://coderwhy/org/prod'// 2.区分环境变量方式二:
// let baseURL = ''
// if (process.env.NODE_ENV === 'production') {
//   baseURL = 'https://coderwhy/org/prod'
// } else if (process.env.NODE_ENV === 'development') {
//   baseURL = 'https://coderwhy/org/dev'
// } else {
//   baseURL = 'https://coderwhy/org/test'
// }// 3.区分环境变量方式三: 加载.env文件
export const API_BASE_URL = process.env.VUE_APP_BASE_URLexport const TIME_OUT = 5000

service/request/type.ts

export interface Result<T> {code: numberdata: T
}

service/index.ts

// 统一出口文件import LWJRequest from "./request/request"
import { API_BASE_URL, TIME_OUT } from './request/config'
import localCache from '@/utils/cache'const lwjRequest = new LWJRequest({baseURL: API_BASE_URL,timeout: TIME_OUT,// 可以让不同的类拥有不同的拦截器,更加灵活interceptorHooks: {// 请求成功拦截requestInterceptor: (config) => {const token = localCache.getCache('token')if (token && config.headers) {config.headers.Authorization = `Bearer ${token}`}return config},// 请求失败拦截requestInterceptorCatch: (err) => {return err},// 响应成功拦截responseInterceptor: (res) => {return res.data},// 响应失败拦截responseInterceptorCatch: (err) => {return err}}
})// export const lwjRequest2 = new LWJRequest({
//   baseURL: '地址2'
// })export default lwjRequest

service/login/login.ts

import lwjRequest from "../index";
import {IAccount,LoginInfo} from './type'// 枚举
enum LoginAPI {AccountLogin = 'login',UserInfo = '/users/',UserMenus = '/role/'
}/*** 登录* @param account * @returns */
export function accountLoginRequest(account: IAccount){return lwjRequest.post<LoginInfo>({url: LoginAPI.AccountLogin,data: account })
}/*** 根据id获取用户信息* @param id * @returns */
export function requestUserInfoById(id: number){return lwjRequest.get({url: LoginAPI.UserInfo + id,})
}/*** 根据当前用户id去请求对应的菜单* @param id * @returns */
export function requestUserMenusByRoleId(id: number) {return lwjRequest.get({url: LoginAPI.UserMenus + id + '/menu'})
}

service/login/type.ts

export interface IAccount {name: string,password: string
}export interface LoginInfo {id: number,name: string,token:string
}// export interface IDataType<T = any> {
//   id: number,
//   token: T
// }

utils/cache.ts

// 封装本地存储方法
class LocalCache {setCache(key: string, value: any) {window.localStorage.setItem(key, JSON.stringify(value))}getCache(key: string) {const value = window.localStorage.getItem(key)if (value) {return JSON.parse(value)}}deleteCache(key: string) {window.localStorage.removeItem(key)}clearLocal() {window.localStorage.clear()}
}export default new LocalCache()

方式二

service/config/index.ts

// 1.区分开发环境和生产环境
// export const BASE_URL = 'http://aaa.dev:8000'
// export const BASE_URL = 'http://aaa.prod:8000'// 2.代码逻辑判断, 判断当前环境
// vite默认提供的环境变量
// console.log(import.meta.env.MODE)
// console.log(import.meta.env.DEV); // 是否开发环境
// console.log(import.meta.env.PROD); // 是否生产环境
// console.log(import.meta.env.SSR); // 是否是服务器端渲染(server side render)let BASE_URL = "";
if (import.meta.env.PROD) {// 生产环境BASE_URL = "http://152.136.185.210:4000";
} else {// 开发环境BASE_URL = "http://152.136.185.210:5000";
}// console.log(BASE_URL);// 3.通过创建.env文件直接创建变量
// console.log(import.meta.env.VITE_URL);export const TIME_OUT = 10000;
export { BASE_URL };

service/request/index.ts

import axios from "axios";
import type { AxiosInstance } from "axios";
import type { LWJRequestConfig } from "./type";// 拦截器: 蒙版Loading/token/修改配置/*** 两个难点:*  1.拦截器进行精细控制*    > 全局拦截器*    > 实例拦截器*    > 单次请求拦截器**  2.响应结果的类型处理(泛型)*/class LWJRequest {instance: AxiosInstance;// request实例 => axios的实例constructor(config: LWJRequestConfig) {this.instance = axios.create(config);// 每个instance实例都添加拦截器this.instance.interceptors.request.use((config) => {// loading/tokenreturn config;},(err) => {return err;});this.instance.interceptors.response.use((res) => {return res.data;},(err) => {return err;});// 针对特定的LWJRequest实例添加拦截器this.instance.interceptors.request.use(config.interceptors?.requestSuccessFn,config.interceptors?.requestFailureFn);this.instance.interceptors.response.use(config.interceptors?.responseSuccessFn,config.interceptors?.responseFailureFn);}// 封装网络请求的方法// T => IHomeDatarequest<T = any>(config: LWJRequestConfig<T>) {// 单次请求的成功拦截处理if (config.interceptors?.requestSuccessFn) {config = config.interceptors.requestSuccessFn(config);}// 返回Promisereturn new Promise<T>((resolve, reject) => {this.instance.request<any, T>(config).then((res) => {// 单词响应的成功拦截处理if (config.interceptors?.responseSuccessFn) {res = config.interceptors.responseSuccessFn(res);}resolve(res);}).catch((err) => {reject(err);});});}get<T = any>(config: LWJRequestConfig<T>) {return this.request({ ...config, method: "GET" });}post<T = any>(config: LWJRequestConfig<T>) {return this.request({ ...config, method: "POST" });}delete<T = any>(config: LWJRequestConfig<T>) {return this.request({ ...config, method: "DELETE" });}patch<T = any>(config: LWJRequestConfig<T>) {return this.request({ ...config, method: "PATCH" });}
}export default LWJRequest;

service/request/type.ts

import type { AxiosRequestConfig, AxiosResponse } from "axios";// 针对AxiosRequestConfig配置进行扩展
export interface LWJInterceptors<T = AxiosResponse> {requestSuccessFn?: (config: AxiosRequestConfig) => AxiosRequestConfig;requestFailureFn?: (err: any) => any;responseSuccessFn?: (res: T) => T;responseFailureFn?: (err: any) => any;
}export interface LWJRequestConfig<T = AxiosResponse>extends AxiosRequestConfig {interceptors?: LWJInterceptors<T>;
}

service/index.ts

import { LOGIN_TOKEN } from '@/global/constants'
import { localCache } from '@/utils/cache'
import { BASE_URL, TIME_OUT } from './config'
import LWJRequest from './request'const lwjRequest = new LWJRequest({baseURL: BASE_URL,timeout: TIME_OUT,interceptors: {requestSuccessFn: (config) => {// 每一个请求都自动携带tokenconst token = localCache.getCache(LOGIN_TOKEN)if (config.headers && token) {// 类型缩小config.headers.Authorization = 'Bearer ' + token}return config}}
})export default lwjRequest

src/global/constants.ts

export const LOGIN_TOKEN = 'login/token'

src/utils/cache.ts

enum CacheType {Local,Session
}class Cache {storage: Storageconstructor(type: CacheType) {this.storage = type === CacheType.Local ? localStorage : sessionStorage}setCache(key: string, value: any) {if (value) {this.storage.setItem(key, JSON.stringify(value))}}getCache(key: string) {const value = this.storage.getItem(key)if (value) {return JSON.parse(value)}}removeCache(key: string) {this.storage.removeItem(key)}clear() {this.storage.clear()}
}const localCache = new Cache(CacheType.Local)
const sessionCache = new Cache(CacheType.Session)export { localCache, sessionCache }

service/login/index.ts

import hyRequest from '..'
import type { IAccount } from '@/types'
// import { localCache } from '@/utils/cache'
// import { LOGIN_TOKEN } from '@/global/constants'export function accountLoginRequest(account: IAccount) {return hyRequest.post({url: '/login',data: account})
}export function getUserInfoById(id: number) {return hyRequest.get({url: `/users/${id}`// headers: {//   Authorization: 'Bearer ' + localCache.getCache(LOGIN_TOKEN)// }})
}export function getUserMenusByRoleId(id: number) {return hyRequest.get({url: `/role/${id}/menu`})
}
文章来源:https://blog.csdn.net/weixin_43285360/article/details/142177914
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ppmy.cn/news/1526972.html

相关文章

在 Android 中,自定义 View 的绘制流程

目录 1. 测量阶段 (onMeasure()) 2. 布局阶段 (onLayout()) 3. 绘制阶段 (onDraw()) 总体绘制流程 注意事项 示例总结 参考资料 在 Android 中&#xff0c;自定义 View 的绘制流程主要包括测量、布局、绘制三个关键步骤。具体来说&#xff0c;自定义 View 的绘制涉及重写…

Effective C++笔记之二十三:非void函数不写return

一.main函数 Qt Creator查看汇编的步骤如下 上图是g编译器下的汇编 eax就是main()函数的返回值 如果删掉return 0&#xff1b; 可以发现编译器还是把eax的值设为了0&#xff0c;由此可见&#xff0c;即使在main函数中不写return 0&#xff0c;编译器还是会默认添加个return 0。…

c++结构体与json自动互转(nlohmann的使用)

说明 nlohmann实现了结构体与json自动互转。 下载 https://github.com/nlohmann/json.git 拷贝include/nlohmann/json.hpp到新建工程 例子 代码 #include <iostream> #include "json.hpp" #include <string> using nlohmann::json; using namespa…

Qt --- 信号和信号槽

前言 Linux信号Signal&#xff0c;系统内部的通知机制&#xff0c;进程间通信方式。 信号源&#xff1a;谁发的信号。 信号的类型&#xff1a;哪种类别的信号。 信号的处理方式&#xff1a;注册信号处理函数&#xff0c;在信号被触发的时候自动调用执行。 Qt中的信号和Lin…

滚雪球学SpringCloud[2.1]:服务注册中心Eureka

全文目录&#xff1a; 前言2.1 服务注册中心EurekaEureka简介与工作原理Eureka的工作原理 配置Eureka Server配置Eureka ClientEureka的自我保护机制自我保护机制的工作原理配置自我保护机制 预告 前言 在上一篇文章中&#xff0c;我们对SpringCloud的概念和微服务架构的基础进…

【matlab】生成 GIF 的函数(已封装可直接调用)

文章目录 前言一、函数输入与输出二、函数代码三、例程&#xff08;可直接运行&#xff09;参考文献 前言 生成 gif 图片时遇到的问题&#xff0c;为了后续调用方便&#xff0c;封装为函数 一、函数输入与输出 输入&#xff1a; cell_figure: cell 数组&#xff0c;数组元素是…

TextCNN:文本卷积神经网络模型

目录 什么是TextCNN定义TextCNN类初始化一个model实例输出model 什么是TextCNN TextCNN&#xff08;Text Convolutional Neural Network&#xff09;是一种用于处理文本数据的卷积神经网&#xff08;CNN&#xff09;。通过在文本数据上应用卷积操作来提取局部特征&#xff0c;…

基于Java、SpringBoot、Vue的加油站管理系统设计

摘要 本系统是一个基于Java、SpringBoot和Vue的加油站管理系统。它旨在提高加油站的运营效率&#xff0c;优化客户服务体验&#xff0c;并通过数据分析支持更精准的业务决策。该系统包括用户管理、汽油管理、站点管理等功能模块。通过这些功能&#xff0c;管理员可以方便地管理…