準(zhǔn)備
創(chuàng)建vue3項目
在 src 的文件下創(chuàng)建 發(fā)送網(wǎng)絡(luò)請求相關(guān)的 文件夾 ???
service
??? service 包含有:
index.ts 統(tǒng)一的出口
?? request 用于封裝axios網(wǎng)絡(luò)請求
?? modules 模塊發(fā)送網(wǎng)絡(luò)請求
?? config 配置項
用于測試發(fā)送 網(wǎng)絡(luò)請求的 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 封裝成一個類,導(dǎo)出這個類
類型問題:
axios.create類型:
攔截器類型問題:
封裝代碼
import axios from 'axios'import type { AxiosInstance } from 'axios'// 攔截器:loading、token、修改配置// AxiosRequestConfig類型中沒有 interceptors 需要擴(kuò)展類型import PKRequestConfig from './type'class PKRequest { instance: AxiosInstance constructor(config: PKRequestConfig) { // 每個實例都會 創(chuàng)建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('實例-> 全局的響應(yīng)成功的攔截:') // res.data => promise的res類型有問題 : 通過泛型解決 return res }, (err) => { console.log('實例-> 全局的響應(yīng)失敗的攔截:') 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 ) } // 網(wǎng)絡(luò)請求泛型; 因為promise的成功的回調(diào) 返回的類型 是創(chuàng)建實例時確定的 // PKRequestConfig<T> : PKRequestConfig中的攔截器 響應(yīng)成功的返回數(shù)據(jù)類型需要和 promise一致 request<T = any>(config: PKRequestConfig<T>) { // 針對網(wǎng)絡(luò)請求 中,有 攔截器 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'// 擴(kuò)展 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
創(chuàng)建 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, // 單獨(dú)的攔截器 // AxiosRequestConfig類型中沒有 interceptors interceptors: { requestSuccessFn: (config) => { console.log('pkRequest2單獨(dú)攔截器:請求成功的攔截') return config }, requestFailedFn: (err) => { console.log('pkRequest2單獨(dú)攔截器:請求失敗的攔截') return err }, reponseSuccessFn: (res) => { console.log('pkRequest2單獨(dú)攔截器:響應(yīng)成功的攔截') return res }, reponseFailedFn: (err) => { console.log('pkRequest2單獨(dú)攔截器:響應(yīng)失敗的攔截') 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 // 根據(jù)請求數(shù)據(jù)設(shè)置數(shù)據(jù)類型interface INews { data: any[] status: number statusText: string config: object headers: any request: any}pkRequest .request<INews>({ url: '/news' }) .then((res) => { // 通過泛型設(shè)置,此時的res類型為 INews console.log('pkRequest1:新聞', res.data, res.status) })pkRequest .request({ //沒有特別寫類型,則是泛型的默認(rèn)值 any url: '/mingxing', interceptors: { requestSuccessFn: (config) => { console.log('/mingxing 請求成功的攔截 :') return config }, reponseSuccessFn: (res) => { console.log('/mingxing 響應(yīng)成功的攔截 :') 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()
文章來源:http://www.zghlxwxcb.cn/news/detail-450045.html
輸出結(jié)果
文章來源地址http://www.zghlxwxcb.cn/news/detail-450045.html
到了這里,關(guān)于Vue3和TypeScript下基于Axios的二次封裝教程的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!