准备
创建vue3项目
在 src 的文件下创建 发送网络请求相关的 文件夹 🗂️
service
🗂️ service 包含有:
index.ts 统一的出口
📁 request 用于封装axios网络请求
📁 modules 模块发送网络请求
📁 config 配置项
用于测试发送 网络请求的 api
- 历史上的今天 https://api.oioweb.cn/api/common/history
- 每日一句英文 https://api.oioweb.cn/doc/common/OneDayEnglish推荐使用 直课堂公开的api http://www.zkt-it.com:5050/jiekou/?target_id=001
baseURL: http://www.zkt-it.com:5050
📁 request
🏷️ index.ts
使用 class
把封装 axios 封装成一个类,导出这个类
类型问题:
axios.create类型:
拦截器类型问题:
封装代码
import axios from 'axios'import type { AxiosInstance } from 'axios'// 拦截器:loading、token、修改配置// AxiosRequestConfig类型中没有 interceptors 需要扩展类型import PKRequestConfig from './type'class PKRequest { instance: AxiosInstance constructor(config: PKRequestConfig) { // 每个实例都会 创建axios this.instance = axios.create(config) // 实例 全局的拦截器 this.instance.interceptors.request.use( (config) => { console.log('实例-> 全局的请求成功的拦截:') return config }, (err) => { console.log('实例-> 全局的请求失败的拦截:') return err } ) this.instance.interceptors.response.use( (res) => { console.log('实例-> 全局的响应成功的拦截:') // res.data => promise的res类型有问题 : 通过泛型解决 return res }, (err) => { console.log('实例-> 全局的响应失败的拦截:') return err } ) // 针对特定的pkRequest实例添加拦截 this.instance.interceptors.request.use( config.interceptors?.requestSuccessFn, config.interceptors?.requestFailedFn ) this.instance.interceptors.response.use( config.interceptors?.reponseSuccessFn, config.interceptors?.reponseFailedFn ) } // 网络请求泛型; 因为promise的成功的回调 返回的类型 是创建实例时确定的 // PKRequestConfig<T> : PKRequestConfig中的拦截器 响应成功的返回数据类型需要和 promise一致 request<T = any>(config: PKRequestConfig<T>) { // 针对网络请求 中,有 拦截器 if (config.interceptors?.requestSuccessFn) { // 单次请求的成功拦截 config.interceptors.requestSuccessFn(config as any) } // 返回的promise return new Promise<T>((resolve, reject) => { this.instance .request<any, T>(config) .then((res) => { if (config.interceptors?.reponseSuccessFn) { res = config.interceptors.reponseSuccessFn(res) } resolve(res) }) .catch((err) => { reject(err) }) }) } get<T = any>(config: PKRequestConfig<T>) { return this.request({ ...config, method: 'GET' }) } post<T = any>(config: PKRequestConfig<T>) { return this.request({ ...config, method: 'POST' }) } delete<T = any>(config: PKRequestConfig<T>) { return this.request({ ...config, method: 'DELETE' }) } put<T = any>(config: PKRequestConfig<T>) { return this.request({ ...config, method: 'PUT' }) } patch<T = any>(config: PKRequestConfig<T>) { return this.request({ ...config, method: 'PATCH' }) }}export default PKRequest
import type { AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'// 扩展 AxiosRequestConfig类型interface PKInterceptors<T = AxiosResponse> { requestSuccessFn?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig requestFailedFn?: (err: any) => any reponseSuccessFn?: (res: T) => T reponseFailedFn?: (err: any) => any}interface PKRequestConfig<T = AxiosResponse> extends AxiosRequestConfig { interceptors?: PKInterceptors<T>}export default PKRequestConfig
📁 config
🏷️ index.ts 主要写配置
export const BASE_URL = 'http://www.zkt-it.com:5050'export const TIME_OUT = 10000// 测试登录获取tokenexport const BASE_URL2 = 'http://codercba.com:5000'
📁 index.ts
创建 PKRequest 的实例。实例可以有多个
例如:
import PKRequest from './request'import { BASE_URL, TIME_OUT } from './config/index'// pkRequest实例const pkRequest = new PKRequest({ baseURL: BASE_URL, timeout: TIME_OUT})// 实例2export const pkRequest2 = new PKRequest({ baseURL: 'https://api.oioweb.cn/api/common', timeout: 8000, // 单独的拦截器 // AxiosRequestConfig类型中没有 interceptors interceptors: { requestSuccessFn: (config) => { console.log('pkRequest2单独拦截器:请求成功的拦截') return config }, requestFailedFn: (err) => { console.log('pkRequest2单独拦截器:请求失败的拦截') return err }, reponseSuccessFn: (res) => { console.log('pkRequest2单独拦截器:响应成功的拦截') return res }, reponseFailedFn: (err) => { console.log('pkRequest2单独拦截器:响应失败的拦截') return err } }})// 实例3:登录 BASE_URL2export const pkRequest3 = new PKRequest({ baseURL: BASE_URL2, timeout: 3000})export default pkRequest
📁 module
🏷️ index.ts
import('./home')import('./year')import('./gettest')import('./login')
🏷️ home.ts
import pkRequest from '..'// home.ts // 根据请求数据设置数据类型interface INews { data: any[] status: number statusText: string config: object headers: any request: any}pkRequest .request<INews>({ url: '/news' }) .then((res) => { // 通过泛型设置,此时的res类型为 INews console.log('pkRequest1:新闻', res.data, res.status) })pkRequest .request({ //没有特别写类型,则是泛型的默认值 any url: '/mingxing', interceptors: { requestSuccessFn: (config) => { console.log('/mingxing 请求成功的拦截 :') return config }, reponseSuccessFn: (res) => { console.log('/mingxing 响应成功的拦截 :') return res } } }) .then((res) => { console.log('pkRequest1:明星', res) })
🏷️ year.ts
import { pkRequest2 } from '..'// year.tspkRequest2 .request({ url: '/history' }) .then((res) => { console.log('pkRequest2:历史上的今天', res) })
🏷️ login.ts
import { pkRequest3 } from '..'const postLoginRequest = async () => { const res = await pkRequest3.post({ url: '/login', data: { name: 'coderwhy', password: '123456' } }) console.log('登录用户信息:') console.table(res.data.data)}postLoginRequest()
文章来源:https://www.toymoban.com/news/detail-450045.html
输出结果
文章来源地址https://www.toymoban.com/news/detail-450045.html
到了这里,关于Vue3和TypeScript下基于Axios的二次封装教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!