vue3中使用ts给axios接口返回数据和传入参数约束类型

您所在的位置:网站首页 axios如何封装接口 vue3中使用ts给axios接口返回数据和传入参数约束类型

vue3中使用ts给axios接口返回数据和传入参数约束类型

2023-11-19 10:50| 来源: 网络整理| 查看: 265

前言

从vue3出来后,使用率越来越高,同时由于vue3由ts编写,对ts支持非常好

越来越多人全面拥抱 vue3+ts 的组合

那么既然用到了ts,肯定就要用好,而不是把它当成 anyScript 来使用,那样就失去了ts的使用意义了

写ts的时候,由于各种类型限制,写起来是比较繁琐的

尤其是当我们在使用 axios 的时候,我们前端本地自己写的可以限制类型

那使用接口后返回的数据该怎么定义约束这些类型呢,让我们的项目更加规范

正文

实际上在axios中也是支持ts的,让我们把它提供的类型进行结合起来

这里我把我的实现思路代码以及注释贴出,以供参考

我们需要思考并实现这几个点

1、如何在请求拦截器的 请求头 上加上我们的 token类型,避免ts类型报错 2、怎么在接口返回数据时约束类型 3、怎么在调用接口时约束入参类型

首先我们按照正常项目思路,创建好我们的axios实例封装文件,在这里定义好相关的类型约束

创建一个 request.ts 文件并创建实例

import axios from 'axios' /* 创建请求实例 */ const service = axios.create({ baseURL: 'https://jsonplaceholder.typicode.com', timeout: 30000 })

然后我们需要改装一下axios自带的类型,并重新自定义为我们需要的类型

这里发现自定义的 RequestConfig 参数类型由于是在调用接口实例时使用的,所以headers非必传项

但是在拦截器器中返回的类型出了问题,请求拦截器中的参数必有 headers 字段,所以这里只能分开写成两个

// 引入 axios自带的 请求接口request参数类型 以及 请求接口headers头参数类型 import type { AxiosRequestConfig, AxiosRequestHeaders } from 'axios' // 1、自定义请求接口headers头参数类型 type RequestHeader = AxiosRequestHeaders & { token?: string } // 2、自定义请求接口request参数类型,可以加一些自己自定义的参数 interface RequestConfig extends AxiosRequestConfig { headers?: RequestHeader // 放入请求头 noNeedToken?: boolean // 该接口是否需要token } interface RequestInterceptorsConfig extends RequestConfig { // 请求拦截器使用 headers: RequestHeader; }

然后在请求拦截器里就可以把相关的自定义参数写上去了

/* 添加请求拦截器 */ service.interceptors.request.use( (config: RequestInterceptorsConfig) => { // 请求拦截 if (config.noNeedToken) { // 自定义的参数,是否不需要token的接口 return config } const token = 'aaaaa' // 这里获取token if (!token) { return Promise.reject(); } if (token) { config.headers.token = token // 请求头中添加token } return config }, (error: AxiosError) => { // 请求错误拦截 return Promise.reject(error); } );

ts的提示出现了,类型检查生效

image-20230517111437341.png

接下来封装 request请求方法 ,约束接口返回数据类型,使用前面定义好的请求接口RequestConfig 类型

/* 封装实例的请求方法 */ // 传入泛型约束返回数据类型 // ApiResponse 主体后端返回格式 interface ApiResponse { code: number; msg: string; data: T; // 这里定义请求返回data数据类型 } export default async function request(config: RequestConfig) { // axios实例的 request 接受的第一个泛型参数,就是返回数据data的类型 return service.request(config).then((res) => res.data); // 返回axios的里data数据 }

这里的 ApiResponse 类型是在一般情况下,我们请求后回来的data数据还会再包裹一层后端定义的状态码、消息、数据,这才是我们需要的,所以也要加上类型

image-20230517105019125-1684291828815-1.png

总算配置好了

接下来在scr下新建api文件夹,创建接口文件,引入这个axios实例并使用,直接在request方法传入后端返回的数据格式即可

import request from "../utils/request"; interface testModel { name: string age: number } export function test() { return request({ method: 'get', url: '/test', }) }

image-20230517115927464.png

image-20230517115943415.png

ts的提示出现了,类型检查生效

以后只需要根据后端接口文档定义好相应的返回数据类型,然后泛型传入quest方法即可

那么怎么约束入参类型呢,只需要在方法入口处限制即可

参数不对就会提示

image-20230517120318441.png

配置完成!

下面贴上完整代码

代码

文件根目录/types/axios.d.ts

import type { AxiosRequestConfig, AxiosRequestHeaders, AxiosError, } from "axios"; // 自定义请求接口headers头参数类型 type RequestHeader = AxiosRequestHeaders & { token?: string } // 自定义请求接口request参数类型,可以加一些自己自定义的参数 export interface RequestConfig extends AxiosRequestConfig { headers?: RequestHeader // 放入请求头 noNeedToken?: boolean // 该接口是否需要token } export interface RequestInterceptorsConfig extends RequestConfig { // 请求拦截器使用 headers: RequestHeader; } // 主体后端返回格式 export interface ApiResponse { code: number; msg: string; data: T; // 这里定义请求返回data数据类型 }

文件根目录/src/utils/request.ts

import axios from "axios"; import type { AxiosError, } from "axios"; import type { RequestConfig, RequestInterceptorsConfig, ApiResponse } from '../../types/axios' /* 创建请求实例 */ const service = axios.create({ baseURL: "xxxxxxxx", timeout: 30000, }); /* 添加请求拦截器 */ service.interceptors.request.use( (config: RequestInterceptorsConfig) => { // 请求拦截 if (config.noNeedToken) { // 自定义的参数,是否不需要token的接口 return config } const token = 'aaaaa' // 这里获取token if (!token) { return Promise.reject(); } if (token) { config.headers.token = token } return config }, (error: AxiosError) => { // 请求错误拦截 return Promise.reject(error); } ); /* 添加响应拦截器 */ service.interceptors.response.use(); /* 封装实例的请求方法 */ export default async function request(config: RequestConfig) { // axios实例的 request 接受的第一个泛型参数,就是返回数据data的类型 return service.request(config).then((res) => res.data); // 返回axios的里data数据 }

文件根目录/src/api/user.ts

import request from "../utils/request"; interface testModel { name: string age: number } interface dataModel { // 接口入参类型 page: number size: number } export function test(data: dataModel) { return request({ method: 'get', url: '/test', data }) } test({page: 1, size: 10}).then(res => { console.log(res) })


【本文地址】


今日新闻


推荐新闻


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