vue3項目中封裝axios的示例代碼
目前前端最流行的網(wǎng)絡(luò)請求庫還是axios,所以對axios的封裝很有必要,此次基于vue3+ts的環(huán)境下。
axios的基本使用
import axios from 'axios' // console.log('adh') axios.get('http://XXX.xxx.xxx.xxx:8000/home').then((res) => { console.log(res.data) })
axios.get()會返回一個Promise對象,所以可以用.then獲取返回的數(shù)據(jù)。
axios.all()方法
axios.all([ axios.get('http://httpbin.org/get').then((res) => { console.log(res.data) }), axios.post('http://httpbin.org/post').then((res) => { console.log(res.data) }) ])
axios一些基本配置
在axios中,有一些默認配置,它們是存在于axios.defaults中的,比如我們經(jīng)常會用到的baseURL、timeout屬性
axios.defaults.baseURL = 'http://httpbin.org' axios.defaults.timeout = 10000
axios的攔截器
在平常的使用中,我們經(jīng)常需要對axios請求進行攔截以處理一些特殊情況,如獲取token、處理異常等,這時候我們就需要使用axios的攔截器()。
axios.interceptors.request.use( (config) => { return config }, (error) => { return error } ) axios.interceptors.response.use( (res) => { console.log(res.data) }, (error) => { return error } )
如上,axios.interceptors.request是對請求的攔截,此時可以為請求添加headers,添加token等操作,二axios.interceptors.response則是對請求的返回進行攔截,在此處我們可以統(tǒng)一返回的數(shù)據(jù)結(jié)構(gòu)以及對錯誤進行一些統(tǒng)一的處理
封裝axios-封裝基礎(chǔ)屬性
首先,我們先確認一下基本思路,我們把主要的邏輯封裝成一個類,然后編寫一個出口文件,將該類導(dǎo)出,需要注意的是,往這個類中傳入哪些參數(shù),誠然,我們可以直接在類中定義諸如BASE_URL、timeout、interceptors等axios的屬性或方法,但是為了今后的可適配性更高,我們應(yīng)該盡量的把可配置的屬性作為變量傳入我們欲封裝的類中,下面先進行一個基本的封裝:
// 封裝類 import axios from 'axios' import { AxiosInstance, AxiosRequestConfig } from 'axios' class ZWRequest { instance: AxiosInstance constructor(config: AxiosRequestConfig) { this.instance = axios.create(config) } request(config: AxiosRequestConfig): void { this.instance.request(config).then((res) => { console.log(res) // 此處能成功打印出結(jié)果代表成功 }) } } export default ZWRequest // 出口文件index.ts import ZWRequest from './request' import { BASE_URL, timeout } from './request/config' const zwRequest = new ZWRequest({ baseURL: BASE_URL, // 配置參數(shù) timeout: timeout // 配置參數(shù) }) export default zwRequest // 在main.ts中測試 import ZWRequest from './service/index.ts' ZWRequest.request({ url: '/post', method: 'POST' })
封裝攔截器
上面的封裝可以傳入BASE_URL、timeout等一些基礎(chǔ)屬性,但是對于攔截器interceptors還是不能實現(xiàn)配置,所以下一步我們改造一下使其可以傳入攔截器:
// 封裝類 import axios from 'axios' import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' // 自建一個用于匹配interceptors的類型 interface ZWRequestInterceptors { requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig // 這是個函數(shù)類型 requestErrorInterceptor?: (error: any) => any responseInterceptor?: (config: AxiosResponse) => AxiosResponse responseErrorInterceptor?: (error: any) => any } /** 再新建一個一個類型繼承AxiosRequestConfig類型,并在其中設(shè)立一個屬性, 該屬性對應(yīng)上一步建立的類型,如此,我們就可以用這個類型來代替封裝類 的constructor()函數(shù)傳入的參數(shù)類型了,在此基礎(chǔ)上,完成對攔截器參數(shù)的傳入。*/ interface ZWRequestConfig extends AxiosRequestConfig { interceptors?: ZWRequestInterceptors } class ZWRequest { instance: AxiosInstance interceptors?: ZWRequestInterceptors constructor(config: ZWRequestConfig) { this.instance = axios.create(config) this.interceptors = config.interceptors this.instance.interceptors.request.use( this.interceptors?.requestInterceptor, this.interceptors?.requestErrorInterceptor ) this.instance.interceptors.response.use( this.interceptors?.responseInterceptor, this.interceptors?.responseErrorInterceptor ) } request(config: ZWRequestConfig): void { this.instance.request(config).then((res) => { console.log(res) }) } } export default ZWRequest // 出口函數(shù)index.ts /** 我們可以在出口函數(shù)中同意規(guī)定攔截器的形式以及相應(yīng)的處理,這樣做的好處是如果我們想 再生成一個可用的axios對象,如ZWRequest2,而且想實現(xiàn)與ZWRequest不一樣的攔截方法,那么 就只需要在該頁面再新創(chuàng)建一個對象即可 */ import ZWRequest from './request' import { BASE_URL, timeout } from './request/config' const zwRequest = new ZWRequest({ baseURL: BASE_URL, timeout: timeout, interceptors: { requestInterceptor: (config) => { console.log('發(fā)送請求成功11', config) return config }, responseInterceptor: (res) => { console.log('返回成功11', res) return res } } }) const zwRequest2 = new ZWRequest({ baseURL: BASE_URL, timeout: timeout, interceptors: { requestInterceptor: (config) => { console.log('發(fā)送請求成功22', config) return config }, responseInterceptor: (res) => { console.log('返回成功22', res) return res } } }) export default zwRequest // main.ts中實驗 ZWRequest.request({ url: '/post', method: 'POST' }) ZWRequest2.request({ url: '/post', method: 'POST' })
封裝公用的攔截器
上面的封裝中,攔截器是由每個實例傳入的,但是有時候我們就是想所有的實例都擁有共同的攔截器,那么我們就需要在axios封裝類里面添加共有的攔截器了(實例傳入的攔截器也并不會被取消),只需要在axios封裝類中添加以下代碼即可實現(xiàn)全局的攔截:
this.instance.interceptors.request.use( (config) => { console.log('共有的請求時成功攔截') return config }, (error) => { console.log('共有的請求時失敗攔截') return error } ) this.instance.interceptors.response.use( (res) => { console.log('共有的返回時成功的攔截') return res }, (error) => { console.log('共有的返回時失敗的攔截') return error } )
對單個請求傳入攔截器
其實上面對攔截器的封裝已經(jīng)基本可以滿足平時的開發(fā)需求了,但是如果你想更靈活些,比如每個請求都可以傳入自己的攔截器,那么請往下看,如果我們需要再請求時傳入攔截器,那么就需要看看我們是怎么調(diào)用的。目前,我們采用ZWRequest.request(config)的方式調(diào)用axios請求,很顯然,在封裝類中,config參數(shù)的類型是:AxiosRequestConfig,這個類型很顯然不能傳入攔截器參數(shù)。
request(config: AxiosRequestConfig): void { this.instance.request(config).then((res) => { console.log(res) }) }
所以為了能夠往request方法中傳入攔截器參數(shù),我們需要將AxiosRequestConfig類型化成我們上面新建立的類型ZWRequestConfig,這樣就可以從單個請求處傳入各自的攔截器了。
// 改造axios封裝類中的request方法 request(config: ZWRequestConfig): 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) }) } // 在main.ts中進行測試 ZWRequest.request({ url: '/post', method: 'POST', interceptors: { requestInterceptor: (config) => { console.log('單獨請求的請求成功攔截') return config }, responseInterceptor: (res) => { console.log('單獨請求的響應(yīng)成功攔截') return res } } })
可以正常打印,成功!
對request請求方法封裝
上面其實已經(jīng)對request請求進行了大部分的封裝了,但是此時的各種返回還局限在類里面,我們在main.ts中是無法拿到的,那么想要拿到返回值,我們就需要進一步操作,其實就是利用promise將結(jié)果返回出來:
// 對request方法的改造 request<T>(config: ZWRequestConfig): Promise<T> { return new Promise((resolve, reject) => { // 對單獨請求傳來的攔截器進行處理 if (config.interceptors?.requestInterceptor) { config = config.interceptors?.requestInterceptor(config) } if (config.showLoading === false) { // 代表該請求不想顯示加載動畫 this.showLoading = config.showLoading } this.instance .request<any, T>(config) .then((res) => { // 每次請求返回后將showLoading的值改為默認值,以免被這次請求穿的配置影響下一次請求的加載動畫顯示 this.showLoading = DEFAULT_LOADING if (config.interceptors?.responseInterceptor) { res = config.interceptors?.responseInterceptor(res) } resolve(res) console.log(res) }) .catch((error) => { console.log(error) this.showLoading = DEFAULT_LOADING reject(error) }) }) } // 在main.ts中實驗 interface dataType { data: any returnCode: string success: boolean } ZWRequest.request<dataType>({ url: '/home/multidata', method: 'GET' // showLoading: false }).then((res) => { console.log(res.data) console.log(res.returnCode) console.log(res.success) })
由上可見,其實操作很簡單,那么接下來即使利用已經(jīng)寫好的request方法來些各種常用的請求調(diào)用方法了,就不多做贅述了,代碼如下:
get<T>(config: ZWRequestConfig): Promise<T> { return this.request<T>({ ...config, method: 'GET' }) } post<T>(config: ZWRequestConfig): Promise<T> { return this.request<T>({ ...config, method: 'POST' }) } delete<T>(config: ZWRequestConfig): Promise<T> { return this.request<T>({ ...config, method: 'DELETE' }) }
以上就是本人對axios的全部封裝,完畢!
到此這篇關(guān)于vue3項目中封裝axios的文章就介紹到這了,更多相關(guān)vue3封裝axios內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue+better-scroll 實現(xiàn)通訊錄字母索引的示例代碼
通訊錄字母索引是常用的一種功能,本文主要介紹了Vue+better-scroll 實現(xiàn)通訊錄字母索引,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06解決項目vite1.0升級到2.0打包遇到Some chunks are larger問題
本文主要介紹了解決項目vite1.0升級到2.0打包遇到Some chunks are larger問題,文中根據(jù)實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03