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协议特别适合需要实时通信的应用,如在线聊天、实时游戏、股票交易、实时监控系统…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...