Typescript使用装饰器封装axios请求

运行环境

装饰器是一项实验性特性,需要在tsconfig.json或tsconfig.app.json中开启配置

{
    "compilerOptions": {
        "target": "ES5",
        "experimentalDecorators": true
    }
}

整体架构流程

  • services 封装的axois服务文件
  • decorator 装饰器文件
  • api文件
  • 页面文件

例如:
在语言模型中,编码器和解码器都是由一个个的 Transformer 组件拼接在一起形成的。

request.ts

封装axios

import axios from 'axios'

const axiosInstance = axios.create({
    timeout: 10000,
    baseURL: ''
})

// 请求拦截
axiosInstance.interceptors.request.use((config) => {
    return config
})
// 响应拦截
axiosInstance.interceptors.response.use(
    (response) => {
        const { data } = response
        return data
    },
    (err) => err
)

interface RequestConfig {
    method: string,
    url: string,
    data: any
}


const request = (config: RequestConfig) => {
    const { method, url, data } = config
    return axiosInstance({ method, url, data })
}

const get = (url: string, params: any) => {
    return request({
        method: 'get',
        url,
        ...params
    })
}

const post = (url: string, params: any) => {
    return request({
        method: 'post',
        url,
        ...params
    })
}
export {
    get,
    post
}

decorator.ts

这里封装了3个修饰器,除了常规的Get 和 Post 请求,还额外加了Result,对返回值格式的处理

1. 方法装饰器(MethodDecorator)
方法装饰器参数有三个,target,key descriptor

  • target: 被装饰的类的实例
  • key: 被装饰的属性名称
  • descriptor: 被装饰属性的属性描述符

2.参数装饰器(ParameterDecorator)
参数装饰器参数有三个,target,methodName ,index

  • target: 被装饰的类的实例
  • methodName : 被装饰的方法名
  • index: 被装饰的参数在函数的参数列表中的索引位置
import 'reflect-metadata'
import { get, post } from '@/services/axiosInstance'

export const Get = (url: string) => {
    const fn: MethodDecorator = (target, key, descriptor: PropertyDescriptor) => {
        const originalMethod = descriptor.value;
        descriptor.value = (...args: any) => {
            const params = args[0]
            const key: string = Reflect.getMetadata('key', target)
            return get(url, params).then((res: any) => {
                return originalMethod.call(this, res[key])
            })
        }
    }
    return fn
}

export const Post = (url: string) => {
    const fn: MethodDecorator = (target, key, descriptor: PropertyDescriptor) => {
        const originalMethod = descriptor.value;
        descriptor.value = (...args: any) => {
            const params = args[0]
            const key: string = Reflect.getMetadata('key', target)
            return post(url, params).then((res: any) => {
                return originalMethod.call(this, res[key])
            })
        }
    }
    return fn
}

export const Result = () => {
    const fn: ParameterDecorator = (target) => {
        Reflect.defineMetadata('key', 'data', target)
    }
    return fn
}

api.service.ts

使用修饰器

import { Get, Result } from '@/decorator'

class UserApi {
    @Get('/getUserApi')
    getUserInfoApi(@Result() data: any) {
        return data
    }
}

export default UserApi

index.service.ts

import $UserApi from './userApi'

export default {
    $UserApi: new $UserApi()
}

home.vue

import UserApi from '@/services'
import { onMounted } from 'vue'

const { $UserApi } = UserApi

const getUserInfo = () => {
  $UserApi.getUserInfoApi({}).then((res: any) => {
    console.log(res)
  })
}

onMounted(() => {
  getUserInfo()
})
好的,以下是使用TypeScript封装Axios拦截器的示例代码: ```typescript import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; class AxiosInterceptor { private axiosInstance: AxiosInstance; constructor(baseURL: string, timeout = 10000) { this.axiosInstance = axios.create({ baseURL, timeout, }); this.requestInterceptor(); this.responseInterceptor(); } private requestInterceptor(): void { this.axiosInstance.interceptors.request.use( (config: AxiosRequestConfig) => { // 在发送请求之前做些什么 // 比如添加token到header中 const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, (error) => { // 对请求错误做些什么 return Promise.reject(error); } ); } private responseInterceptor(): void { this.axiosInstance.interceptors.response.use( (response: AxiosResponse) => { // 对响应数据做点什么 return response; }, (error) => { // 对响应错误做点什么 if (error.response.status === 401) { // token失效,跳转到登录页 window.location.href = '/login'; } return Promise.reject(error); } ); } public get<T>(url: string, config?: AxiosRequestConfig): Promise<T> { return this.axiosInstance.get<T>(url, config); } public post<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> { return this.axiosInstance.post<T>(url, data, config); } public put<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> { return this.axiosInstance.put<T>(url, data, config); } public delete<T>(url: string, config?: AxiosRequestConfig): Promise<T> { return this.axiosInstance.delete<T>(url, config); } } export default AxiosInterceptor; ``` 这个类使用Axios的拦截器功能,在请求发送前和响应返回后进行一些操作,比如添加token到请求header中,或者在token失效后跳转到登录页。类中还封装了常用的get、post、put、delete等HTTP请求方法,可以直接调用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值