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

news2024/12/30 2:54:50

系列文章目录

本系列记录一下通过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: string
    password: string
  }
  export interface LoginResponse {
    access_token: string
    name: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 封装代码里,通过响应拦截器处理。各有各的优缺点。等先把页面样式写好,再看看写到哪里比较合适。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1161695.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三菱MC协议及报文格式详解

一、简介 三菱MC协议是指三菱电机公司&#xff08;Mitsubishi Electric&#xff09;使用的一种通信协议&#xff0c;用于在三菱PLC&#xff08;可编程逻辑控制器&#xff09;和其他设备之间进行数据交换和通信。 三菱MC协议有多个版本&#xff0c;最常见的是MC-Protocol&…

uniapp原生插件之安卓USB扫码枪扫码插件

插件介绍 安卓USB扫码枪扫码&#xff0c;监听USB扫码枪 插件地址 安卓USB扫码枪扫码插件 - DCloud 插件市场 超级福利 uniapp 插件购买超级福利 插件方法 开启监听&#xff1a;setListener 重要说明&#xff1a;当开启监听后当前窗体不可点击&#xff0c;点击无任何…

最新夸克网盘 迅雷网盘 UC网盘cpa拉新推广教程 推广申请渠道

最近很多朋友都想做夸克网盘、迅雷网盘、uc网盘的推广 但是找不到申请渠道 可以通过”聚量推客“进行申请&#xff0c;一手渠道价格高 数据好 接下来&#xff0c;让我们开始夸克网盘、迅雷网盘、UC网盘的开通操作教程&#xff1a; 目前市面上&#xff0c;这三家网盘统一的地…

mathtype最新7.4.10.53绿色版本下载

MathType&#xff0c;一款功能强大的数学公式编辑器&#xff0c;一直深受广大用户的喜爱&#xff0c;给很多的理科生和各位学者、教研机构等带来巨大帮助。 软件的主要使用用户为初中、高中以及大学的学生、老师&#xff0c;理工科专业工作者&#xff0c;可用于编辑数学试卷、…

Python画图之动态爱心

Python画出动态爱心&#xff08;有趣小游戏&#xff09; 一、效果图二、Python代码 一、效果图 二、Python代码 import random from math import sin, cos, pi, log from tkinter import *CANVAS_WIDTH 640 # 画布的宽 CANVAS_HEIGHT 480 # 画布的高 CANVAS_CENTER_X CANV…

CoCa论文笔记

摘要 计算机视觉任务中&#xff0c;探索大规模预训练基础模型具有重要意义&#xff0c;因为这些模型可以可以极快地迁移到下游任务中。本文提出的CoCa&#xff08;Contrastive Captioner&#xff09;&#xff0c;一个极简设计&#xff0c;结合对比损失和captioning损失预训练一…

Spring中的核心概念

&#x1f388;个人公众号:&#x1f388; :✨✨✨ 可为编程✨ &#x1f35f;&#x1f35f; &#x1f511;个人信条:&#x1f511; 知足知不足 有为有不为 为与不为皆为可为&#x1f335; &#x1f349;本篇简介:&#x1f349; 本篇记录Spring中的核心概念&#xff0c;如有出入还…

QQ文件怎么恢复?3个方法解决文件丢失问题!

无论是在学习还是工作中&#xff0c;我们都有可能需要接触到QQ这款软件。QQ传输文件十分方便&#xff0c;因此仍然有许多小伙伴喜欢用QQ来发送各种类型的文件。对于大家来说&#xff0c;最害怕的莫过于重要的文件出现丢失的情况。 当我们发现QQ文件意外删除或者过期时该怎么办…

【第28例】IPD体系进阶 | 需求管理:需求实现过程

目录 简介 内容详解 CSDN学院相关推荐 作者简介 简介 继续 IPD 体系中的需求管理相关的专题。 先来看看整个需求管理涉及的过程内容: 需求管理流程主要包含五个阶段: 需求收集; 需求分析; 需求分发/分配;

软件开发项目文档系列之九如何撰写测试方案

测试方案是任何软件开发和项目实施过程中的重要组成部分&#xff0c;它提供了确保系统质量和可靠性的蓝图。通过明确定义测试的范围、策略、资源和计划&#xff0c;测试方案确保项目团队明白如何有效地执行测试&#xff0c;并提供客观的评估和反馈。它有助于降低项目风险&#…

【PyTorch 卷积】实战自定义的图片归类

前言 卷积神经网络是一类包含卷积计算且具有深度结构的前馈神经网络&#xff0c;是深度学习的代表算法之一&#xff0c;它通过卷积层、池化层、全连接层等结构&#xff0c;可以有效地处理如时间序列和图片数据等。关于卷积的概念网络上也比较多&#xff0c;这里就不一一描述了。…

苹果手机黑屏了怎么恢复正常?这些修复方法记得收藏好!

苹果手机黑屏是一种常见的手机故障&#xff0c;很多人在遇到手机突然黑屏的情况时感到束手无策。手机黑屏会干扰用户的正常使用&#xff0c;带来不便&#xff0c;并给用户带来不好的体验。苹果手机黑屏了怎么恢复正常&#xff1f;本文将为大家详细介绍修复苹果手机黑屏的方法。…

3.网络之UDP

UDP协议 文章目录 UDP协议1. UDP概述2. UDP报文格式3. UDP传输限制4. UDP校验和4.1 CRC 循环冗余校验算法4.2 md5 校验算法 1. UDP概述 UDP&#xff08;UserDatagramProtocol&#xff09;是一个简单的面向消息的传输层协议&#xff0c;尽管UDP提供标头和有效负载的完整性验证&a…

Linux指令【下】

目录 时间 date 时间戳 cal 查找 find which whereis grep uniq 打包压缩 zip/unzip tar uname 其他热键 关机 系统互传 linux和Windows Linux和Linux 时间 date 用法&#xff1a;date[option] [format] 选项功能%Y年%d日%m月%H时%M分%s秒%X%H:%M%S%F%Y-%…

「Java开发指南」如何用MyEclipse搭建Spring MVC应用程序?(一)

本教程将指导开发者如何生成一个可运行的Spring MVC客户应用程序&#xff0c;该应用程序实现域模型的CRUD应用程序模式。在本教程中&#xff0c;您将学习如何&#xff1a; 从数据库表的Scaffold到现有项目部署搭建的应用程序 使用Spring MVC搭建需要MyEclipse Spring或Bling授…

【MySQL数据库】 一

本文主要介绍了关系型数据库和非关系数据库的区别,以及主流的关系型数据库mysql的安装 , 以及mysql数据库客户端-服务器的结构. 一.数据库的分类 我们可以简单的把数据库看成是一类软件 数据库分成两大类 1.关系型数据库 通常以表格的方式来组织 2.非关系型数据库 通常以键值…

电脑关机很慢?这几个优化技巧请收好!

当我们使用电脑时&#xff0c;一个令人不快的问题是&#xff0c;关机变得异常缓慢。电脑在关机时可能需要很长时间&#xff0c;甚至让人感到沮丧。这不仅是时间浪费&#xff0c;还可能表明系统存在问题。在本文中&#xff0c;我们将介绍四种解决电脑关机很慢的方法&#xff0c;…

怎么向国外客户催单?这样做既有效又不让客户反感

外贸业务员接单的过程其实是一场利益博弈的过程&#xff0c;而且外贸销售永远靠结果说话&#xff0c;所以无论你的客户如何承诺&#xff0c;甚至有时候都已经签订了定单合同做了PI&#xff0c;但客户钱没到账公司&#xff0c;一切就有可能归零。 01 心态一定要稳住 对于每个有…

如何在业务代码中优雅地使用责任链模式

通过使用责任链模式&#xff0c;我们可以更加灵活和优雅地处理请求&#xff0c;降低代码之间的耦合度&#xff0c;提高代码的可维护性和可扩展性。在一些具有复杂业务逻辑或需要动态处理请求的场景下&#xff0c;使用责任链模式将是一个很好的选择。本文将通过一个具体的示例来…

【错误解决方案】ModuleNotFoundError: No module named ‘tensorboardX‘

1. 错误提示 在python程序中&#xff0c;尝试导入一个名为tensorboardX的模块&#xff0c;但Python提示找不到这个模块。 错误提示&#xff1a;ModuleNotFoundError: No module named ‘tensorboardX‘ 2. 解决方案 在python出现中&#xff0c;遇到这个问题是Python无法找到…