TS axios封装
方式一
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`})
}
相关文章:

TS axios封装
方式一 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.typ…...

学会使用西门子博途Startdrive中的测量功能
工程师在驱动调试过程中,往往需要对驱动系统的性能进行分析及优化,比如说借助于调试软件中的驱动器测量功能,可以得到驱动系统的阶跃响应、波特图等,以此为依据工程师可以调整速度控制器、电流控制器的相关参数,使驱动…...

Spring Security认证与授权
1 Spring Security介绍 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。由于它是Spring生态系统中的一员,因此它伴随着整个Spring生态系统不断修正、升级,在spring boot项目中加入springsecurity更是…...

速通GPT:Improving Language Understanding by Generative Pre-Training全文解读
文章目录 速通GPT系列几个重要概念1、微调的具体做法2、任务感知输入变换3、判别式训练模型 Abstract概括分析和观点1. 自然语言理解中的数据问题2. 生成预训练和监督微调的结合3. 任务感知输入变换4. 模型的强大性能 Introduction概括分析和观点1. 自然语言理解的挑战在于对标…...

软件质量保证例题
答案:D 软件质量保证 功能性 适合性 准确性 互操作性 安全保密性 依从性 可靠性 成熟性 容错性 易恢复性 易用性 易理解性 易学性 易操作性 效率 时间特性 资源利用性 维护性 易分析性 易改变性 稳定性 易测试性 可移植性 适应性 易安装性 一致性 易替换…...

动态规划算法---04.斐波那契数列模型_解码方法_C++
题目链接:91. 解码方法 - 力扣(LeetCode)https://leetcode.cn/problems/decode-ways/description/ 一、题目解析 题目: 题目大意:从题目中我们可以知道,解码就是在字符串s中由‘1’到‘26’的字符可以转化…...

crm如何做私域运营?
流量获取的挑战日益增加,客户线索成本高、客户资源流失严重、转化率低,因此,私域流量管理已成为关键。 当前挑战 1、公域流量难以整合:外部流量分散,难以有效汇总和沉淀。 2、私域运营体系缺失:缺乏有效沟…...

基于QGIS 3.16.0 的OSM路网矢量范围裁剪实战-以湖南省为例
目录 前言 一、相关数据介绍 1、OMS路网数据 2、路网数据 3、路网图层属性 二、按省域范围进行路网裁剪 1、裁剪范围制定 2、空间裁剪 3、裁剪结果 三、总结 前言 改革开放特别是党的十八大以来,我国公路发展取得了举世瞩目的成就。国家高速公路网由“7 射…...

WPF 手撸插件 八 依赖注入
本文内容大量参考了:https://www.cnblogs.com/Chary/p/11351457.html 而且这篇文章总结的非常好。 1、注意想使用Autofac,Autofac是一个轻量级、高性能的依赖注入(DI)框架,主要用于.NET应用程序的组件解耦和…...

走进低代码报表开发(一):探秘报表数据源
在前文当中,我们对勤研低代码平台的流程设计功能进行了介绍。接下来,让我们一同深入了解在企业日常运营中另一个极为常见的报表功能。在当今数字化时代,高效的报表生成对于企业的决策至关重要。勤研低代码开发平台能够以卓越的性能和便捷的操…...

代理服务器及其原理
代理服务器的代理可以分为正向代理和反向代理,本篇将讲解这两种代理方式的原理,以及对应的功能特点和应用场景。最后还对比和 NAT 和代理服务器的区别。 目录 正向代理 工作原理 功能特点 应用场景 反向代理 基本原理 应用场景 NAT和代理服务器…...

计算机毕业设计选题推荐-养老院管理系统-Java/Python项目实战
✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...

免费SSL证书正在逐渐被淘汰,证书部署自动化的发展趋势即将到来!
目录 背景解决方案。1.使用自签证书(浏览器报警、免费)2.更换支持自签自续的CA机构(免费)3.付费选择CA机构 免费SSL证书正在逐渐被淘汰,证书部署自动化的发展趋势即将到来免费的SSL证书有以下弊端1.有效期短࿱…...

openVX加速-基本概念和简单代码实现
OpenVX 是一个用于计算机视觉和图像处理的跨平台加速标准库,旨在提高在异构平台(如 CPU、GPU、DSP 等)上的执行效率。OpenVX 提供了一组优化的、可移植的 API,用于加速常见的视觉算法,使开发者能够在不同硬件平台上实现…...

网工内推 | 网络工程师,Base上海,HCIP/HCIE认证优先
01 利宏科技 🔷招聘岗位:网络工程师 🔷任职要求 1、有HCIE、HCIP证书 2、做过IDC机房网络建设 3、本科毕业 4、熟悉基本linux命令 5、熟悉山石、华为等防火墙 6、熟悉IPS、WAF等安全设备 7、做过同城灾备机房建设优先 🔷薪…...

Windows10 如何配置python IDE
Windows10 如何配置python IDE 前言Python直接安装(快速上手)Step1.找到网址Step2.选择版本(非常重要)Step3. 安装过程Step4. python测试 Anaconda安装(推荐,集成了Spyder和Pycharm的安装)Step1…...

Machine Learning: A Probabilistic Perspective 机器学习:概率视角 PDF免费分享
下载链接在博客最底部!! 之前需要参考这本书,但是大多数博客都是收费才能下载本书。 在网上找了好久才找到免费的资源,浪费了不少时间,在此分享以节约大家的时间。 链接: https://pan.baidu.com/s/1erFsMcVR0A_xT4fx…...

信息学奥赛:青少年编程的高光舞台,通向未来科技的敲门砖
近年来,信息学奥林匹克竞赛(NOI,National Olympiad in Informatics)逐渐成为众多中学生学习编程、展示才华的热门赛事。这项被誉为“编程天才选拔赛”的竞赛,不仅考验学生的编程能力、算法思维,更是通向名校…...

Android - NDK:在Jni中打印Log信息
在Jni中打印Log信息 1、在配置CMakeLists.txt find_library( # Sets the name of the path variable.log-lib# Specifies the name of the NDK library that# you want CMake to locate.log)# Specifies libraries CMake should link to your target library. You # can link…...

websocket协议解说
WebSocket是一种在单个TCP连接上进行全双工通信的协议。 它为客户端和服务器之间提供了一个持久的连接,允许数据以帧的形式在客户端和服务器之间进行双向传输。 WebSocket协议特别适合需要实时通信的应用,如在线聊天、实时游戏、股票交易、实时监控系统…...

InternVL2-多模态模型原理-多模态模型和组合模型
好的,我会尽量用简单易懂的语言来解释InternVL和InternVL 1.5的工作原理。 InternVL和InternVL 1.5的工作原理 1. 模型结构 InternVL和InternVL 1.5都是由两个主要部分组成:一个视觉模型和一个语言模型。 视觉模型:负责处理图片信息。它的…...

大语言模型之ICL(上下文学习) - In-Context Learning Creates Task Vectors
本文译自 《In-Context Learning Creates Task Vectors》 —— 论文中的作者也在用LLaMA模型,笔者自我感觉拉近和世界顶级人才的距离,哈哈内容较长,如想看结论直接看 摘要、介绍与结论几个章节即可,看细节请看目录索引。经验风险最…...

出现错误消息“ sshd[xxxx]: error: no more session ”的原因是什么?
环境 • 红帽企业 Linux 6 • Red Hat Enterprise Linux 7 • openssh 问题 • SSH 选项的用途是什么MaxAuthTries,MaxSessions和MaxStartups? 解决 MaxAuthTries :指定每个连接允许的最大身份验证尝试次数。一旦失败次数达到此值的一半&…...

代码随想录训练营第29天|控制变量
134. 加油站 class Solution { public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int cur0, total0, start0;for(int i0; i<gas.size(); i){curgas[i]-cost[i];totalgas[i]-cost[i];if(cur<0){starti1;cur0;}}if(start>gas…...

毕业论文选题难?5招帮你轻松搞定选题!
AIPaperGPT,论文写作神器~ https://www.aipapergpt.com/ 你是不是已经为毕业论文的选题愁得头发都要掉光了?每次打开文档,都觉得什么都想写,又好像什么都写不了。选题看起来很简单,但真正开始动手的时候,…...

[QT]记事本项目(信号槽,QT基础控件,QT文件操作,QT关键类,对话框,事件)
一.UI界面搭建 (ui界面使用,界面布局,各控件介绍,界面大小调整) 二.信号槽机制实现文件的打开,保存,退出 (信号槽,QFile文件类,QTextStream类,QFileDialog文件对话框࿰…...

redis基本数据结构-hash
这里写自定义目录标题 1. redis的数据结构hash1.1 Hash 数据结构的特点1.2 常见命令1.3 适用示例 2. 常见业务场景2.1 用户信息存储2.1.1 场景2.1.2 优势2.1.3 解决方案2.1.4 代码实现 2.2 购物车管理2.2.1 背景2.2.2 优势2.2.3 解决方案2.2.4 代码实现 3. 注意事项:…...

21. 什么是MyBatis中的N+1问题?如何解决?
N1 问题是指在进行一对多查询时,应用程序首先执行一条查询语句获取结果集(即 1),然后针对每一条结果,再执行 N 条额外的查询语句以获取关联数据。这个问题通常出现在 ORM 框架(如 MyBatis 或 Hibernate&…...

天空卫士项目荣获“2024 IDC 中国20大杰出安全项目 ”奖项 ,实力见证安全守护
9月11日, IDC在上海圆满举办安全风险管控峰会,并现场官宣“2024 IDC中国20大杰出安全项目(CSO20) ”和“2024 IDC中国 CSO名人堂 (十大人物) ” 奖项名单。联通软研院申报的联通邮件系统安全合规建设项目被评为“2024 IDC中国20大杰出安全项目(CSO20) ”…...

Android生成Java AIDL
AIDL:Android Interface Definition Language AIDL是为了实现进程间通信而设计的Android接口语言 Android进程间通信有多种方式,Binder机制是其中最常见的一种 AIDL的本质就是基于对Binder的运用从而实现进程间通信 这篇博文从实战出发,用一个尽可能…...