当前位置: 首页 > news >正文

Day 5 登录页及路由 (三) 基于axios的API调用

系列文章目录

本系列记录一下通过Abp搭建后端,Vue+Element UI Plus搭建前端,实现一个小型项目的过程。

  • Day 1 Vue 页面框架
  • Day 2 Abp框架下,MySQL数据迁移时,添加表和字段注释
  • Day 3 登录页以及路由 (一)
  • Day 4 登录页以及路由 (二)Vue状态管理

文章目录

  • 目录

    系列文章目录

    文章目录

    前言

    一、axios

    二、封装还是不封装,这是个问题

    1. 封装的目的

    2. 怎么封装

    3. 到底要不要封装


前言

作为前后端分离的系统,请求后端API是一个必不可少的工作,本文就介绍了Vue中调用后端API的基础内容。


一、axios

Vue官方推荐使用axios来进行网络请求,于是先到axios的官网上看了一遍文档,其介绍是这样的:

Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。

大致看了一下官方文档,发现功能已经很齐全了,唯一需要处理的就是针对特定系统的配置性处理。程序员之魂开始燃烧,封印术已经按捺不住了。

二、封装还是不封装,这是个问题

1. 封装的目的

老套路,先看看别人怎么做的(程序员的事情,怎么能叫抄呢 🤣)。搜索一下,有做简单封装的(比如 这个 ),有做复杂封装的(比如这个和这个),同时评论区也有人疑惑为何要封装,是不是和axios背道而驰。

首先,封装的目的,总结下来大致有这么几个:

  1.  统一请求头。大部分项目对应的后端,需要统一请求头,比如app,version,token之类的。既然是统一,那天然的就应该是放在封装层里面。
  2. 错误处理。根据API返回结果,或者更底层一点,根据HttpStatus来进行通用的错误处理。啊哈,通用,懂了把。
  3. 重试及取消操作。在网络世界,不通是常见的“偶发”问题。或者是连接失败,或者是服务器错误,或者是太阳黑子影响,总之,反应到页面上就是无法访问。然后刷新一下就神奇的好了。另外,操作响应时间不固定,性急的人往往会连击,而响应不一定是按请求顺序返回,或者直接不返回。不做处理的话,容易造成数据混乱,页面卡死之类的。这个时候取消一下前面的请求,让页面只对最后一个请求结果进行处理,会简化处理逻辑。同样,这个“应该”也是一个统一处理。
  4. 开发过程中的配置。设置接口请求前缀:根据开发、测试、生产环境的不同,前缀需要加以区分。我的理解这是一个伪需求, axios本身的baseUrl就是干这个的。
  5. 觉得axios是第三方库,对项目而言需要隔离一下,以备将来换成别的库。这个就见仁见智了,解耦到这个程度,还是需要一些勇气的。另外,你确定不是在重复设计axios?
  6. 就是单纯不封装不舒服,不服来战

2. 怎么封装

具体封装的手段大致有两个:

  1. 依赖拦截器,无论是请求拦截器还是响应拦截器,都是axios提供的扩展点。
  2. 封装常用代码为方法。即把get、post等常用请求方法,再封装一次。这个我以为仅限于项目中对这些方法有特定需要的。因为axios本身就有别名方法,够满足大部分需要了。

3. 到底要不要封装

看了一圈下来,结合官方文档,我感觉二次封装有必要,但过度封装就没有必要了,搭建一个架子,把基本目标实现了就可以了,其它的后续再根据需求调整,渐进式开发嘛。

其实,从后端开发的角度来看,封装axios就和封装WebRequest,HttpClient之类的一样,根据实际需要来就行。要克制,过度设计有害健康。

另外,大部分文章都提到了将实际api的调用封装起来,放到单独的文件中去(比如api\xxxManage.ts)。这个我赞成,和后端服务层或数据访问层的作用一样。这么看,axios就和DBDriver一样,属于偏底层的库(当然,它的底层是XmlHttpRquest 和 node.js http 模块)。

基础研究到此为止,开始重复发明轮子。

三、实际操作

1. 代码结构

创建 src/api 文件夹,下面创建 index.ts 文件,axios的封装代码就写在这里了。然后针对不同的领域,建立不同的api封装文件。比如 login.ts 就封装登录相关api,提供给LoginView使用。

2. 调用端代码

参照TDD的方式,先写最顶层调用端代码

src/view/LoginView.vue

async function fakeLogin(event: Event) {//currentUser.setToken("faked login token")const loginRequest: Login.LoginRequest = { username: "test", password: "pw" }const loginResponse: Login.LoginResponse = await login(loginRequest)currentUser.setToken(loginResponse.access_token)currentUser.setUserInfo({ name: loginResponse.name })
}

伪代码一路到底,这里利用了语法糖, await还是很甜的。

然后定义login api 的封装接口,这里没有想好login方法是否要放入Login命名空间,暂时先这样吧。

src/api/login.ts

// 登录模块
export namespace Login {export interface LoginRequest {username: stringpassword: string}export interface LoginResponse {access_token: stringname:string}  
}export const login = async (params: Login.LoginRequest) => {console.log("call async login.")const response:LoginResponse = { access_token:"token", name:"test user"}return response
}

测试一下,看看效果,点击Fake Login按钮后:

3. API 接入实现

先做基础配置工作,src/api/index.ts

import axios, { AxiosError } from 'axios'
import type { InternalAxiosRequestConfig } from 'axios'import { BASE_URL } from '@/config'
import { useCurrentUserStore } from '@/stores/currentUser'const instance = axios.create({baseURL: BASE_URL,timeout: 3000,  
})instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {// 当前用户已登录的情况下,添加Authorization请求头const userStore = useCurrentUserStore()if (userStore.token != '') {if (config.headers && typeof config.headers.set === 'function') {config.headers.set('Authorization', userStore.token)}}return config},(error: AxiosError) => {return Promise.reject(error)}
)export default instance

到这个阶段,暂时只是添加token到请求头里,其实这个都算早的,只是为了使用下拦截器,而且确实也是后面需要的功能,所以先写下来。后面错误处理还没有弄,这个需要结合页面表现再看。

另外就是BASE_URL直接使用了config的配置,关于环境的切换,发布时直接更改这个也不是很麻烦,暂时就先这样了。

重写 src/api/login.ts

import http from '@/api'
import type { Login, ResultDTO } from './interfaces'export const login = async (params: Login.LoginRequest
): Promise<ResultDTO<Login.LoginResponse>> => {const { data } = await http.post('/api/account/login', params)return data
}

把请求和响应移到 interfaces文件中,统一管理了。这个只是一个习惯,看将来大概会从什么角度来阅读代码。所有请求放到一个文件,方便上手就能看到整体。放到接近使用的地方,比如login.ts中,则可以在使用的地方就知道具体含义,不过IDE的Go to definition功能也是很好用的。

interfaces里面还包括了后端响应基类,没有采用REST的推荐,自定义了Code,具体代码如下:

src/api/interface.ts

/** API响应 */
export interface ResultBase {/** 响应代码 */code: string/** 消息 */message: string/** 是否成功 */success: boolean
}
/** API响应 */
export interface ResultDTO<T> extends ResultBase {/** 数据 */data: T
}// 登录模块
export namespace Login {/** 登录请求 */export interface LoginRequest {/** 用户名 */username: string/** 密码 */password: string}/** 登录响应账号信息 */export interface LoginResponse {/** Token */token: string/** 用户昵称 */nickname: string}
}

四、总结

前面搞了一大堆,实际代码没有多少,另外错误处理也还没有弄,但是理清了思路。这里有一个点,就是src/api/login.ts 这个文件是否有必要,因为就是一行代码,封装成函数似乎有点重复且繁复。暂时留在这里也是为了错误处理,还没有思考具体错误处理是留在这里,还是放到view层,或者直接在 axios 封装代码里,通过响应拦截器处理。各有各的优缺点。等先把页面样式写好,再看看写到哪里比较合适。

相关文章:

Day 5 登录页及路由 (三) 基于axios的API调用

系列文章目录 本系列记录一下通过Abp搭建后端&#xff0c;VueElement UI Plus搭建前端&#xff0c;实现一个小型项目的过程。 Day 1 Vue 页面框架Day 2 Abp框架下&#xff0c;MySQL数据迁移时&#xff0c;添加表和字段注释Day 3 登录页以及路由 (一&#xff09;Day 4 登录页以…...

雷神学习---视音频数据处理入门:RGB、YUV像素数据处理

原文地址&#xff1a;https://blog.csdn.net/leixiaohua1020/article/details/50534150 ​​​​​​​​从代码可以看出&#xff0c;如果想把YUV格式像素数据变成灰度图像&#xff0c;只需要将U、V分量设置成128即可。 这是因为U、V是图像中的经过偏置处理的色度分量。色度分…...

Asp.Net Core服务端处理请求过来的压缩格式

之前是直接传没有经过压缩的文件字节&#xff0c;有时文件过大的话&#xff0c;可能占宽带就多&#xff0c;宽带流量都是钱。后来有个想法&#xff0c;在客户端把文件进行压缩&#xff0c;把压缩的文件流发给服务端进行解压。 1&#xff0c;先修改项目中Startup.cs文件中Confi…...

自定义指令

二、自定义指令 1.指令介绍 内置指令&#xff1a;v-html、v-if、v-bind、v-on… 这都是Vue给咱们内置的一些指令&#xff0c;可以直接使用 自定义指令&#xff1a;同时Vue也支持让开发者&#xff0c;自己注册一些指令。这些指令被称为自定义指令 每个指令都有自己各自独立的功…...

仿真实现lio_sam建图和ndt_matching定位

文章目录 一、仿真环境二、lio_sam建图1.修改配置文件2.开始建图 三、ndt_matching定位1.新建启动文件2.启动 总结 一、仿真环境 使用现有开源的仿真环境—从零开始搭建一台ROS开源迷你无人车&#xff0c;作者已经配置好小车模型以及gazebo环境&#xff0c;imu频率已改为200HZ…...

IDEA取消git对项目的版本控制

前言 前几天新建项目的时候不小心选了个git仓库&#xff0c;导致这个测试项目一直被git管理着。 解决办法 1 右键项目 选择打开资源目录 2 删除.git文件 把目录下的.git文件删掉 3 删除idea中的git管理 删除完.git文件后&#xff0c;进入idea&#xff0c;右下角会有这样的提…...

如何聪明地编写测试

作者&#xff5c;Maxim Schepelin Booking公司软件开发工程师 编译整理&#xff5c;TesterHome 以下为作者观点&#xff1a; 在我&#xff08;作者&#xff09;的职业生涯中&#xff0c;我多次看到团队如何开始自动化测试&#xff0c;当然并非所有尝试都成功。在这篇文章中…...

CF1866M Mighty Rock Tower

CF题面 luogu题面 期望题。 题目大意&#xff1a;一个人在搭积木&#xff0c;每次堆叠可能成功或失败&#xff0c;失败可能导致其下面连续的若干块掉落。给定搭每一块时失败的概率&#xff0c;求堆叠完成的期望次数。 具体的&#xff0c;假设当前正在堆叠第 i 块&#xff0c;…...

【漏洞复现】Apache_Tomcat7+ 弱口令 后台getshell漏洞

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 说明内容漏洞编号漏洞名称Tomcat7 弱口令 && 后台getshell漏洞漏洞评级高…...

2023-11-7 OpenAI 45 分钟发布会:演示关于 GPT Store 构建 GPT、零代码创建 AI Agent

本心、输入输出、结果 文章目录 2023-11-7 OpenAI 45 分钟发布会&#xff1a;演示关于 GPT Store 构建 GPT、零代码创建 AI Agent前言Sam Altman 正在创建一个「创业导师 GPT」零代码创建 AI AgentAssistants API 封装的能力包括 Sam Altman 对发布会总结相关链接弘扬爱国精神 …...

嵌入式系统中的FPGA

举个栗子 假设你有一台智能家居系统&#xff0c;其中的FPGA可以被类比为智能家居中的中央控制器。 智能家居系统&#xff1a; 定制家居逻辑&#xff1a; 你希望智能家居系统能够根据你的生活习惯、时间表和喜好自动控制灯光、温度、窗帘等设备。就像FPGA中可以根据需求重新配置…...

String,StringBulider,StringBuffer的简单说明

目录 1.String 2.StringBuffer 3.StringBuilder 4.线程安全的验证 1.String String是声明在java.lang下的一个类。 String被定义为final&#xff0c;表示不能被继承。内部定义了final char value[]用于存储字符串数据&#xff0c;所以String对象的值是不可改变的。每次对S…...

Python编程题集(第一部分基本语法基础)

Demo01 摄氏温度转化为华氏温度 题目描述&#xff1a; 输入一个摄氏温度的值&#xff0c;将它转变为华氏温度&#xff0c;并将结果输出 转换的公式为如下&#xff1a;fahrenheit (9 / 5 ) * celsius 32 输入输出描述 输入一个值表示摄氏温度celsius 输出华氏温度fahren…...

手动关闭PS中的TopazStudio2的登录窗口

2021 adobe photoshop Topaz Studio 2 不是使用防火墙出站规则&#xff0c;是手动关闭的解决方案 点击社区-切换用户&#xff0c;登录窗口会出现X&#xff0c;可以手动关闭...

[elastic 8.x]java客户端连接elasticsearch与操作索引与文档

初始化客户端 引入相关依赖 <dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.10.2</version> </dependency>初始化客户端 为了方便演示&#xff0c;我关闭了ela…...

接口测试总结

本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什么要做&#xff1f; 第二部分&#xff1…...

计算机基础知识44

overflow溢出属性 visible&#xff1a;默认值&#xff0c;内容不会被修剪&#xff0c;会呈现在元素框之外。hidden&#xff1a;内容会被修剪&#xff0c;并且其余内容是不可见的。scroll&#xff1a;内容会被修剪&#xff0c;但是浏览器会显示滚动条以便查看其余的内容。auto: …...

【StringBuilder和StringBuffer】

文章目录 StringBuilder和StringBufferString类、StringBuilder和StringBuffer的区别 StringBuilder和StringBuffer的区别StringBuilder 字符串逆置 StringBuilder和StringBuffer String类、StringBuilder和StringBuffer的区别 String类的特点是不可变性&#xff0c;所以Stri…...

用java代码实现security

Java中security的实现主要涉及到以下几个方面&#xff1a; 认证(Authentication) 认证是确认用户身份的过程&#xff0c;Java中提供了不同的认证机制来保护应用程序不被未授权的用户访问。常用的认证机制有以下几种&#xff1a; 基于口令的认证&#xff1a;要求用户输入用户名…...

【Java 进阶篇】Java Session 原理及快速入门

大家好&#xff0c;欢迎来到本篇博客。今天&#xff0c;我们将探讨Java Web开发中一个重要而令人兴奋的概念&#xff0c;即Session&#xff08;会话&#xff09;。Session是一种在Web应用程序中跟踪用户状态和数据的机制。我们将深入了解Session的原理&#xff0c;并通过示例来…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

算法—栈系列

一&#xff1a;删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...