TypeScript封装axios【包括详细的请求接口和设置】 |
您所在的位置:网站首页 › vue封装接口 › TypeScript封装axios【包括详细的请求接口和设置】 |
问题描述
现在我们的项目需要升级,技术栈为Vue3+TypeScript。所以,现在我需要使用TS对axios进行重新封装 封装目标 调用接口时,只需要确定url和method出现多个请求地址时,通过修改.env类似文件即可,无需修改源代码 封装过程 1.安装axios使用npm安装axios依赖 npm install axios将其封装为一个类,而不是一个函数。 因为类可以创建多个实例,也就是说可以访问完全不同的服务器的接口。 其中可能出现的问题 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); })现在对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); })现在的结果 在创建的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现在的请求结果 就是在这里,我自闭了好久根本搞不懂别人是怎么做的。 因为一开始我根本对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", }若是不满足定义的类型,则会报错 但是!!!这里注意的是 虽然静态报错,但是依旧可以运行成功!!!,暂时还没有找到解决办法阻断运行 总结 运行成功~ 而是只有当真正走投无路的时候,才开始去尝试其他的方法,有点过度依赖博客的感觉! 最后成功其实是借鉴了一些类似Vue3+TS的开源项目的封装思想。 所以这也提醒了我一个问题,当在百度中找不到你想要答案的时候,去看看其他人同类型的项目,获取就会豁然开朗 毕竟,一个程序员都是从借鉴学习开始的! |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |