Vue3+TS+axios封装补充,加入拦截器

参考Vue3+TS+axios封装
以下封装思想来自coderwhy课程

希望在给类YPRequest传入BASE_URL,TIME_OUT的同时,可以传入拦截器

// service 统一出口
import YPRequest from './request'
import { BASE_URL, TIME_OUT } from './request/config'
const ypRequest = new YPRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT
  //加入拦截器
  //hooks:{}
})

// export const ypRequest2 = new YPRequest()
// baseURL:地址一
//这里创造不同的实例,用instance作为区分
export default ypRequest

但是,能直接传入hooks吗?显然是不能的,因为传入YPRequest的参数,是有要求的。
在这里插入图片描述
只有下列的参数能传进去
在这里插入图片描述
所以为了在new YPRequest创造实例的过程中,添加拦截器,必须自定义类型符合ts的检测。
1.先定义传进来的拦截器的类型
拦截器的本质就是一个个函数

import { AxiosRequestConfig, AxiosResponse } from 'axios'
export interface YPRequestInterceptors {
  requestinterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig
  requestinterceptorCatch?: (error: any) => any
  responseinterceptor?: (config: AxiosResponse) => AxiosResponse
  responseinterceptorCatch?: (error: any) => any
} //定义传入进来的拦截器



requestinterceptor:请求拦截
requestinterceptorCatch:请求失败拦截
responseinterceptor:响应拦截
responseinterceptorCatch响应失败拦截

2.定义接口,取代之前(constructor里的参数必须是AxiosRequestConfig)

export interface YPRequestConfig extends AxiosRequestConfig {
  interceptors?: YPRequestInterceptors
}

给他拓展一个interceptors
3.重新拓展类 YPRequest

class YPRequest {
  instance: AxiosInstance //instance 用于区分,当有多个请求时,是用不同的实例

  interceptors?: YPRequestInterceptors
  constructor(config: YPRequestConfig) {
    //可以点击config进去看里面的类型
    this.instance = axios.create(config)
    this.interceptors = config.interceptors
    //以下两个ues对传入的拦截器进行调用
    this.instance.interceptors.request.use(
      this.interceptors?.requestinterceptor,
      this.interceptors?.requestinterceptorCatch
    ) //
    this.instance.interceptors.response.use(
      this.interceptors?.responseinterceptor,
      this.interceptors?.responseinterceptorCatch
    )
  }
  request(config: AxiosRequestConfig): void {
    this.instance.request(config).then((res) => {
      console.log(res.data)
    })
  }
}

4.在创建实例时传入拦截器

// service 统一出口
import YPRequest from './request'
import { BASE_URL, TIME_OUT } from './request/config'
const ypRequest = new YPRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT,
  interceptors: {
    //拦截器的本质是传入一个个函数
    requestinterceptor: (config) => {
      console.log('请求成功的拦截')
      return config
    },
    requestinterceptorCatch: (err) => {
      console.log('请求失败的拦截')
      return err
    },
    responseinterceptor: (res) => {
      console.log('响应成功的拦截')
      return res
    },
    responseinterceptorCatch: (err) => {
      console.log('响应失败的拦截')
      return err
    }
  }
})

// export const ypRequest2 = new YPRequest()
// baseURL:地址一
//这里创造不同的实例,用instance作为区分
export default ypRequest

思路总结:
1.先定义一个class YPRequest类
2.通过new YPRequest可以创造实例ypRequest,同时可以传入BASE_URL,TIME_OUT、拦截器等信息。
3.通过上一步,信息只为上面实例所有。
4.由于写好了request,所以只要调用ypRequest.request(//传入信息)即可

在这里插入图片描述
因为一般一个项目只请求一个BASE_URL,所以通常只创建一个实例。

补充,加上全局的拦截器(所有实例都有的拦截器)和 给某一请求添加特定拦截器

// 关于axios的封装,都封装到这个类里面,因为类具备很强的封装性,比函数要强
import axios from 'axios'
import type { AxiosInstance } from 'axios' //axios内部已经提供了关于axios实例的类型
import type { YPRequestInterceptors, YPRequestConfig } from './type'
// interface YPRequestInterceptors {
//   requestinterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig
//   requestinterceptorCatch?: (error: any) => any
//   responseinterceptor?: (config: AxiosResponse) => AxiosResponse
//   responseinterceptorCatch?: (error: any) => any
// } //定义传入进来的拦截器

// interface YPRequestConfig extends AxiosRequestConfig {
//   interceptors?: YPRequestInterceptors
// }

class YPRequest {
  instance: AxiosInstance //instance 用于区分,当有多个请求时,是用不同的实例

  interceptors?: YPRequestInterceptors
  constructor(config: YPRequestConfig) {
    //可以点击config进去看里面的类型
    this.instance = axios.create(config)
    this.interceptors = config.interceptors

    //从config中取出的拦截器是对应的实例的拦截器
    this.instance.interceptors.request.use(
      this.interceptors?.requestinterceptor,
      this.interceptors?.requestinterceptorCatch
    ) //
    this.instance.interceptors.response.use(
      this.interceptors?.responseinterceptor,
      this.interceptors?.responseinterceptorCatch
    )

    //添加所有的实例都有的拦截器
    this.instance.interceptors.request.use(
      (config) => {
        console.log('这是所有实例都有的拦截器')
        return config
      },
      (err) => {
        return err
      }
    )
  }
  request(config: YPRequestConfig): void {
    if (config.interceptors?.requestinterceptor) {
      config = config.interceptors.requestinterceptor(config)
    }
    this.instance.request(config).then((res) => {
      if (config.interceptors?.responseinterceptor) {
        res = config.interceptors.responseinterceptor(res)
      }
      console.log(res.data)
    })
  }
}

export default YPRequest

//给特定实例拦截器
ypRequest.request({
  url: '/home/multidata',
  method: 'GET',
  interceptors: {
    requestinterceptor: (config) => {
      console.log('单独成功的拦截')
      return config
    }
  }
})
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是封装Vue3 + TypeScript + Axios的示例代码: 1. 创建一个`api.ts`文件,用于存放API请求路径: ```typescript // api.ts const BASE_URL = 'https://api.example.com'; export const API_PATHS = { getUsers: `${BASE_URL}/users`, getPosts: `${BASE_URL}/posts`, // 添加其他API路径... }; ``` 2. 创建一个`request.ts`文件,用于封装Axios请求方法: ```typescript // request.ts import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import { API_PATHS } from './api'; // 创建一个Axios实例 const instance = axios.create({ baseURL: API_PATHS.BASE_URL, timeout: 5000, // 设置请求超时时间 }); // 请求拦截 instance.interceptors.request.use( (config: AxiosRequestConfig) => { // 在请求发送之前可以进行一些处理,例如添加请求头等 return config; }, (error: any) => { // 处理请求错误 return Promise.reject(error); } ); // 响应拦截 instance.interceptors.response.use( (response: AxiosResponse) => { // 在接收到响应数据之前可以进行一些处理,例如解析响应数据等 return response.data; }, (error: any) => { // 处理响应错误 return Promise.reject(error); } ); // 封装GET请求方法 export const get = (url: string, params?: any) => { return instance.get(url, { params }); }; // 封装POST请求方法 export const post = (url: string, data?: any) => { return instance.post(url, data); }; // 添加其他请求方法,例如PUT、DELETE等... ``` 3. 在需要使用Axios的地方,引入`request.ts`并调用封装的请求方法: ```typescript import { get, post } from './request'; // 使用GET请求获取用户列表 get(API_PATHS.getUsers) .then((response: any) => { // 处理响应数据 console.log(response); }) .catch((error: any) => { // 处理请求错误 console.error(error); }); // 使用POST请求创建新用户 const newUser = { name: 'John', age: 25 }; post(API_PATHS.getUsers, newUser) .then((response: any) => { // 处理响应数据 console.log(response); }) .catch((error: any) => { // 处理请求错误 console.error(error); }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值