TypeScript封装axios【包括详细的请求接口和设置】

您所在的位置:网站首页 vue封装接口 TypeScript封装axios【包括详细的请求接口和设置】

TypeScript封装axios【包括详细的请求接口和设置】

2023-11-19 14:07| 来源: 网络整理| 查看: 265

问题描述

现在我们的项目需要升级,技术栈为Vue3+TypeScript。所以,现在我需要使用TS对axios进行重新封装

封装目标 调用接口时,只需要确定url和method出现多个请求地址时,通过修改.env类似文件即可,无需修改源代码 封装过程 1.安装axios

使用npm安装axios依赖

npm install axios

在这里插入图片描述

2.实现基本封装 首先导入axios创造构造器设置request import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; class Request { private instance: AxiosInstance | undefined constructor(config: AxiosRequestConfig) { this.instance = axios.create(config) } request(config: AxiosRequestConfig): Promise { return new Promise((resolve, reject) => { this.instance?.request(config) .then((res) => { resolve(res) }) .catch((err) => { reject(err) }) }) } }

将其封装为一个类,而不是一个函数。 因为类可以创建多个实例,也就是说可以访问完全不同的服务器的接口。

其中可能出现的问题 Cannot find module ‘axios;‘ or its corresponding type declarations.ts(2307)

3.创建实例

我想通过不同的运行环境创建不同的实例,所以设置如下 创建.env文件 根据vue-cli 模式与环境变量官方写到,可根据env后指定mode即可创建不同的请求路径 创建.env.development——用于开发环境

NODE_ENV = development VUE_APP_BASE_URL = "http://你的开发请求的地址"

创建.env.production——用于正式部署环境

NODE_ENV = production VUE_APP_BASE_URL = "http://正式部署时请求的地址"

创建实例 因为我根据不同环境去设置变量时候,地址名字都是VUE_APP_BASE_RUL所以,可以根据此去创建axios请求的baseUrl

import Request from "./request"; /** * process.env.VUE_APP_BASE_URL 根据NODE_ENV变化而变化 */ const web: Request = new Request({ baseURL: process.env.VUE_APP_BASE_URL, }) export default web

现在尝试在main.ts中调用一个接口

import web from './utils/request/index' web.request({ url: '/login', }) .then((res) => { console.log(res); })

在这里插入图片描述

4.添加响应和请求拦截器

现在对request.ts进行优化升级(添加拦截器+泛型——复用性)

import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'; // import type { AxiosInstance , AxiosResponse } from 'axios'; class Request { private instance: AxiosInstance | undefined constructor(requeseConfig: AxiosRequestConfig) { this.instance = axios.create(requeseConfig) // 全局请求拦截 this.instance.interceptors.request.use( (config) => { console.log("全局请求拦截的", config); return config }, (error) => { console.log("全局请求拦截失败", error); }, ) // 全局响应拦截 this.instance.interceptors.response.use( (res) => { // res 为AxiosResponse 类型,含有conig\data\headers\request\status\statusText属性 console.log("全局响应拦截的", res); return res.data // 只需要返回data即可 }, (error) => { console.log("全局响应失败拦截"); console.log(error.request); console.log(error.response); return error }, ) } request(config: AxiosRequestConfig): Promise { return new Promise((resolve, reject) => { /* eslint-disable */ this.instance?.request(config) .then((res) => { resolve(res) }) .catch((err) => { reject(err) }) }) } } export default Request

再次在main.ts中调用

web.request({ url: '/login', }) .then((res) => { console.log(res); }) .catch((err) => { console.log(err); })

现在的结果 在这里插入图片描述

5.在请求头中添加token

在创建的index.ts中,添加token

import Request from "./request"; /** * process.env.VUE_APP_BASE_URL 根据NODE_ENV变化而变化 */ /* eslint-disable */ const token = String(window.localStorage.getItem('token')) const web: Request = new Request({ baseURL: process.env.VUE_APP_BASE_URL, timeout: process.env.VUE_APP_TIME_OUT, headers: { 'Content-Type': 'application/json', 'Accept': "application/json", 'Authorization': token, }, }) export default web

现在的请求结果 在这里插入图片描述 现在请求的接口,带上了token,便于后端进行权限控制

6.封装GET,POST方法 get(url: string) { return new Promise((resolve, reject) => { this.instance?.post(url) .then((res) => { resolve(res.data) }) .catch((err) => { reject(err.data) }) }) } post(url: string, data = {}) { return new Promise((resolve, reject) => { this.instance?.post(url, data) .then((res) => { resolve(res.data) }) .catch((err) => { reject(err.data) }) }) }

就是在这里,我自闭了好久根本搞不懂别人是怎么做的。 因为一开始我根本对axios和ts都没有一个理解和认知,所以对于更加抽象的封装就显得无能为力了。 然后我就开始尝试看之前我们项目的代码结合其他开源项目的操作,就想到直接传url和data并给data一个初始值。

7.定义对应后端的Ts的接口

因为我希望对项目进行模块化的封装,于是创建了专门封装接口的api文件夹,文件夹下根据模块新建文件夹。 这里以user模块下的login为例 在api模块下,我创建了models.ts,里面存放所有与后端对应接口的类型接口 例如: 后端的登录接口可以接受参数login包括

邮箱:string密码:string验证码:string时间错:string

于是在userModels.ts下定义接口如下

// 登录接口 export interface login { accountEmail: string, accountPassword: string, code: string, data: string, } 8.实现接口的封装

同样的继续创建login.ts文件,去实现接口 代码如下:

import web from "@/utils/request"; import { login } from "../models"; export default function login(requesrData?: login) { const responesData = web.post('/login', requesrData) return responesData; } 因为后端可以不传入任何参数所以使用?:去定义类型 当有参数时,遵守login接口类型当没有参数时,直接进入即可 9.开始调用接口

在对应的页面进行调用接口

来吧,试试一个接口看看 import login from '@/api/user/login'; const a = 1; console.log(a); const login= async () => { await login({ accountEmail: "[email protected]", accountPassword: "xxxxxxxxxxxxxx", code: "2xl4", data: "1647152454419", }

若是不满足定义的类型,则会报错 请添加图片描述

但是!!!这里注意的是 虽然静态报错,但是依旧可以运行成功!!!,暂时还没有找到解决办法阻断运行

总结

运行成功~ 请添加图片描述 成功的那一刻是喜悦的!!!毕竟这算是自己独立封装出来的 虽然可能一些可拓展性存在缺陷,但终究结果也是可以接受的。这次用TS去封装axios有点快要自闭的感觉,自己对这些东西理解不深,然后看那些为了可扩展性和高复用性进行高度抽象的封装,就有些不知所措了,而且在这个过程中,自己没有及时的去真正尝试去理解。

而是只有当真正走投无路的时候,才开始去尝试其他的方法,有点过度依赖博客的感觉!

最后成功其实是借鉴了一些类似Vue3+TS的开源项目的封装思想。

所以这也提醒了我一个问题,当在百度中找不到你想要答案的时候,去看看其他人同类型的项目,获取就会豁然开朗

毕竟,一个程序员都是从借鉴学习开始的!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3