乐趣区

关于typescript:ts封装axios

axios 拦截器能够让咱们在我的项目中对后端 http 申请和响应主动拦挡解决,缩小申请和响应的代码量,晋升开发效率同时也不便我的项目前期保护。在申请响应的 interceptors(因特塞泼特斯). 这个外面的话. 他分为申请拦截器和响应拦截器, 申请拦截器外面个别在申请头外面携带 token 值. 响应拦截器外面对状态码的判断. 比方说返回 401 的时候就是 token 没权限. 跳转到登录界面.

封装 axiso 首先下载

npm install axios

创立文件夹 request,在文件夹中创立 index.ts 文件名,开始对 axios 进行手动封装封装 或 官网复制粘贴拦截器(https://www.axios-http.cn/docs/interceptors)

  1. 首先引入下载好的 aixos
  2. 创立实例
  3. 申请拦挡,别离蕴含申请胜利 和 申请谬误两个函数

    1. 执行机会为:发动申请时,申请还没有发送进来时执行 申请拦挡
    2. 申请胜利:申请头携带 token
    3. 申请谬误:产生谬误申请时,能够解决 4 结尾的谬误
  4. 响应拦挡,别离包响应胜利 和 响应失败两个函数

    1. 执行机会为:申请完结后,服务器有响应的时候执行
    2. 响应胜利:返回状态码为 2xx(200…)携带的数据
    3. 响应失败:响应失败 / 谬误时,能够对 5 结尾的状态码进行解决、申请超时、谬误状态码的解决。
  5. 导出封装好的 axios

手动封装 axios 代码详情

// 引入 axios
import axios from axios
// 进度条和款式
import nProgress from "nprogress" // npm install nprogress
import "nprogress/nprogress.css"
// 实例化 axios
const install = axios.create({
    // 申请地址的前缀 公共全局的 URL
    baseURL:"",
    // 申请时长  --- 超出定义的时长,申请超时
    timeout:5000
})
// 申请拦挡
install.interceptors.request.use((config)=>{
        // 开始进度条
        nProgress.start()
        // 获取 token
        const token = localStorge.getItem('token')
        // 申请头携带 token    
        config.headers[''] ="Bearer " + token
        return config
    },
    (error)=>{return Promise.reject(error)
    }
)
// 响应拦挡
install.interceptors.response.use((response)=>{
        // 响应胜利敞开进度条
        nProgress.done()
        // 返回响应的数据
        return response
    },
    (error)=>{
        // 申请超时解决
        if(error.message.includes('timeout')){alert('申请超时')
            return;
        }
        // 不同谬误状态码解决
        const code = error.response.status;
        switch(code){
            case 400:
                console.log('申请谬误');
                break;
            case 401:
                console.log('未受权');
                break;
            case 403:
                console.log('禁止拜访');
                break;
            case 404:
                console.log('页面隐没');
                break;
            case 500:
                console.log('服务器外部谬误');
                break;
            case 502:
                console.log('网关谬误');
                break;
        }
        return Promise.reject(error)
    }
)
// 导出封装好的 aixos

以上是 axios 两次封装,咱们还能够将他们的申请形式也封装一下,比方在同文件夹内新建一个 methods.ts 文件,而后如下代码:

// 引入封装好的 axios
import install from "./index"
// 定义任意类型接口
interface anyType{[key:string]:any | (string|number)
}
// 定义类型接口
interface dataType{
    url:string, // 门路
    method?:string,  // 申请办法 get / post...
    headers?:anyType, // 申请头
    params?:anyType, // get 申请携带参数用的
    data?:anyType, // post 申请携带参数用的
}

// 创立 get 申请办法
export const get = (data:dataType)=>{
    // 定义申请办法
    data.method = "GET"
    // 返回
    return install(data)
}

// 创立 post 申请办法
export const = (data:dataType)=>{
    // 定义 post 申请办法
    data.method = "POST"
    // 返回
    return install(data)
}

URL=http://172.16.10.111:5886/#/

模仿申请

// 引入封装好的 get post 申请办法
import {get,post} from "./methods"

// 模仿一个申请接口
export const getLogin = (data) =>{
    return get({
        url:"申请的门路",
        data:data // 传递参数
    })
}

最初只须要在组件内调用 getLogin 这个办法即可。

更具体的封装

/**
 * 
 * axios
 * 
 * 封装 axios 逻辑
 * 1. 下载依赖
 * 2. 创立文件
 * 3. 导入 / 引入 axios
 * 4. 增加默认配置
 * 5. 定义返回的数据类型
 * 6. 增加拦截器
 * 7. 封装申请办法
 * 8. 导出 / 抛出 实例
 * 
 * 
 * 1.AxiosInstance 
 *   示意:*       axios 实例的配置项 url 办法 headers 参数
 * 2.AxiosRequestConfig
 *   示意:*      axios 实例的类型
 * 3.AxiosResponse 
 *   示意:*      axios 响应的数据结构 状态码 响应头 响应数据
 * 4.AxiosError
 *   示意:
 *      axios 申请产生谬误的谬误对象 错误信息  申请配置
 * 5.InternalAxiosRequestConfig
 *   示意:*      扩大了 AxiosRequestConfig 接口
 * 
 */

// 导入
import axios, {AxiosInstance, AxiosResponse, AxiosRequestConfig, AxiosError, InternalAxiosRequestConfig} from 'axios';

// 默认配置 实例化
const instance: AxiosInstance = axios.create({
    baseURL: import.meta.url || "", // 设置 api 的根本门路 相当于 默认的根目录
    timeout: 5000, // 申请时长
})

// 申请拦截器
instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
        // 
        return config;
    },
    // 申请地址谬误
    (error: AxiosError) => {return Promise.reject(error);
    }
)

// 响应拦截器
instance.interceptors.response.use((response: AxiosResponse) => {
        // 判断
        if (response.status === 200) {return response.data} else {
            // 如果响应状态码不是 200 返回一个回绝的 Promise
            // Promise 三个状态 别离 胜利,失败,进行中
            return Promise.reject()}
    },
    (error: AxiosError) => {// return Promise.reject(error);
        throw new Error("Http Error:" + error)
    }
)

// 导出
export default instance

// 定义后果 接口的 result 
// unknown 未知类型
export interface Result<T = unknown> {
    message: string;
    code: number;
    data: T;
    [key: string]: any; // 其余任意类型
}

// 申请后果的类型 Result

/* 
    定义一个名为 Result 的接口 默认类型为 泛型 T unknown 未知类型
        接口是一种用户形容对象构造的类型
    接口的属性都有
        message:字符串类型,代表后果的音讯信息
        code:数字类型,代表后果的状态
        data:泛型类型 T, 代表后果的数据 默认为 unknown 类型
        [key:string]:any:索引签名,代表接口能够具备任意数量的其余属性,属性名为字符串类型,属性值为任意类型
            
    PS:
        通过定义这个接口,咱们能够在代码中应用 Result 类型来示意一个具备特定构造的后果对象。例如,能够应用 Result<number> 来示意一个具备数字类型数据的后果对象。*/



// 定义后果接口的 result
export interface Result<T = unknown> {
  message: string;
  code: number;
  data: T;
  [key: string]: any; // 其余的任意类型
}
// axios.get("xxxx", { params: {} });
export const http = {get<T = any>(url: string, params?: object): Promise<Result<T>> {console.log(params);

    return service.get<T, Result<T>>(url, { params});
  },
  post<T = any>(url: string, data?: object): Promise<Result<T>> {return service.post<T, Result<T>>(url, data);
  },
  put<T = any>(url: string, data?: object): Promise<Result<T>> {return service.put<T, Result<T>>(url, data);
  },
  delete<T = any>(url: string, data?: object): Promise<Result<T>> {return service.delete<T, Result<T>>(url, data);
  },
};


export const http = {// axios.get('xxx 门路',{params:{}}) 原型
    get<T = any>(url: string, params?: object): Promise<Result<T>> {return instance.get<T, Result>(url, {params})
    },
    post<T = any>(url:string,data?:object): Promise<Result<T>> {return instance.post<T, Result<T>>(url, {data});
     },
    put<T = any>(url:string,data?:object): Promise<Result<T>> {return instance.put<T,Result<T>>(url, {data});
     },
    delete<T =any>(url:string,data?:object): Promise<Result<T>> {return instance.delete<T,Result<T>>(url, {data});
     },
}
   解析 
    这段代码是应用 TypeScript 定义的一个 HTTP 申请库的封装。这段代码次要蕴含两个局部,一个是 Result 接口,另一个是 http 对象。Result 接口
    Result 接口定义了返回后果的通用构造。它蕴含以下属性:message: 字符串类型,通常用于形容操作的后果音讯。code: 数字类型,通常用于示意操作的返回状态码。data: 能够是任何类型,用于存储申请返回的数据。[key: string]: any;: 这是一个残余属性,意味着能够增加任何其余类型的属性。这个接口能够用来定义 HTTP 申请的响应格局,使得调用者能够不便地解决返回后果。http 对象
    http 对象提供了常见的 HTTP 申请办法,并对每个办法进行了泛型参数化,使得返回后果能够灵便地适应不同的数据类型。get 办法:用于发送 GET 申请。它承受一个 URL 和可选的参数对象,返回一个 Promise 对象,该 Promise 在申请实现后解析为 Result 类型。调用示例:http.get<User>('/users/123').
    post 办法:用于发送 POST 申请。它承受一个 URL、一个可选的申请数据对象,返回一个 Promise 对象,该 Promise 在申请实现后解析为 Result<T> 类型,其中 T 是申请数据对象的类型。调用示例:http.post<User>('/users', userData).
    put 办法:用于发送 PUT 申请。它承受一个 URL、一个可选的申请数据对象,返回一个 Promise 对象,该 Promise 在申请实现后解析为 Result<T> 类型,其中 T 是申请数据对象的类型。调用示例:http.put<User>('/users/123', userData).
    delete 办法:用于发送 DELETE 申请。它承受一个 URL 和一个可选的申请数据对象,返回一个 Promise 对象,该 Promise 在申请实现后解析为 Result<T> 类型,其中 T 是申请数据对象的类型。调用示例:http.delete<User>('/users/123').

*** 如何调用和创立接口
    这段代码没有明确提供如何创立和实例化接口或类的具体步骤,因而无奈提供对于这部分的具体阐明。但通常来说,你能够应用 TypeScript 的类和接口来创立和实例化对象,而后应用这些对象的办法。例如:typescript
    复制代码
    import {http, Result} from './http'; // 导入 http 和 Result 接口  

    // 应用 http.get 发送 GET 申请  
    http.get<User>('/users/123').then(response => {console.log(response.data); // 打印返回的用户数据  
    });
    
    
    
   详解
    /* 
        get 申请办法 办法名为 get
        应用了 泛型 <T = any>
            默认是类型为 any(任意类型)
        
        get<T = any>(url:string,params?:object):Promise<Result = unknow>{return aixos.get<T,Result<T>>(url,params)
        }
    
         他承受两个参数 
            第一个是 url(门路)字符串类型
            第二个是 params(承受参数的)可选参数 对象类型
        get 办法 返回一个 promise 对象
            这个对象是一个未知类型的 Result(申请后果)对象

        函数外部 调用了 axios 中 get 申请办法,同时传入了 url(字符串类型) 和 params(可选对象类型)
            外部的 get 申请办法也应用了泛型
                他承受两个类型参数
                    第一个类型参数是 T(any)第二个类型参数是 Result<T>
                返回一个 Promise 对象
                    返回的 Promise 对象的后果可能是一个 T 类型的值
                    或者是一个 Result<T> 类型的值
                  
        总结:
            这个办法的作用是发送一个 Get 申请,返回一个 Promise 对象,这个 Promise 对象的后果是一个 Result 对象
                Result 对象可能蕴含一个 T 类型的值,也可能是蕴含一个 Result<T> 类型的值

    */
    
    发送一个申请,默认类型泛型 (any) 任意类型   返回一个 promise 对象,承受两个参数 url(字符串类型) 和 params(可选参数类型对象)
    输出 一个 aixos 申请形式默认类型 泛型 或 Result 泛型,传递两个参数 url 和 params(ps:已定义好类型))

援用 / 调用

引入
import {http} from '@/utils/Request'

    http.get('www.baidu.com').then(res=>{console.log(res,'111');
    })
退出移动版