vue+ts下對(duì)axios的封裝實(shí)現(xiàn)
雖然vue中axios的使用已經(jīng)十分方便,但是實(shí)際我們的日常操作中可能為了接口的規(guī)則一致,來(lái)創(chuàng)建一個(gè)統(tǒng)一管理的全局方法達(dá)到簡(jiǎn)化操作.而且在實(shí)際接口對(duì)接中,我們大多都需要對(duì)請(qǐng)求和響應(yīng)進(jìn)行攔截來(lái)進(jìn)行token以及回調(diào)狀態(tài)碼的處理.那么我基于自己的需求簡(jiǎn)單分裝了一下.(之前很少接觸vue,主要用的ng和react,這次新項(xiàng)目想用vue來(lái)弄,熟悉一下vue的一些新特性和方法,有啥不對(duì)的,歡迎大家批評(píng)指正)
前提: 熟悉前端ts, node等等.
1. 安裝axios
npm install axios -D
2. 攔截器及全局方法編寫(xiě)
一個(gè)http.ts文件進(jìn)行自己http邏輯的封裝,為了代碼分離,我同時(shí)創(chuàng)建interceptors.ts文件進(jìn)行攔截器邏輯,放在一起也行.
interceptors.ts(攔截器,進(jìn)行請(qǐng)求和響應(yīng)攔截并進(jìn)行部分邏輯處理)
import axios from 'axios';
import {message} from 'ant-design-vue'; // 這是我引入的antd的組件庫(kù),為了方便彈出吐司
export class Interceptors {
public instance: any;
constructor() {
// 創(chuàng)建axios實(shí)例
this.instance = axios.create({timeout: 1000 * 12});
// 初始化攔截器
this.initInterceptors();
}
// 為了讓http.ts中獲取初始化好的axios實(shí)例
public getInterceptors() {
return this.instance;
}
// 初始化攔截器
public initInterceptors() {
// 設(shè)置post請(qǐng)求頭
this.instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
/**
* 請(qǐng)求攔截器
* 每次請(qǐng)求前,如果存在token則在請(qǐng)求頭中攜帶token
*/
this.instance.interceptors.request.use(
(config) => {
// 登錄流程控制中,根據(jù)本地是否存在token判斷用戶(hù)的登錄情況
// 但是即使token存在,也有可能token是過(guò)期的,所以在每次的請(qǐng)求頭中攜帶token
// 后臺(tái)根據(jù)攜帶的token判斷用戶(hù)的登錄情況,并返回給我們對(duì)應(yīng)的狀態(tài)碼
if (config.headers.isJwt) {
const token = localStorage.getItem('id_token');
if (token) {
config.headers.Authorization = 'Bearer ' + token;
}
}
return config;
},
(error) => {
console.log(error);
},
);
// 響應(yīng)攔截器
this.instance.interceptors.response.use(
// 請(qǐng)求成功
(res) => {
if (res.headers.authorization) {
localStorage.setItem('id_token', res.headers.authorization);
} else {
if (res.data && res.data.token) {
localStorage.setItem('id_token', res.data.token);
}
}
if (res.status === 200) {
return Promise.resolve(res.data);
} else {
this.errorHandle(res);
return Promise.reject(res.data);
}
},
// 請(qǐng)求失敗
(error) => {
const {response} = error;
if (response) {
// 請(qǐng)求已發(fā)出,但是不在2xx的范圍
this.errorHandle(response);
return Promise.reject(response.data);
} else {
// 處理斷網(wǎng)的情況
// eg:請(qǐng)求超時(shí)或斷網(wǎng)時(shí),更新state的network狀態(tài)
// network狀態(tài)在app.vue中控制著一個(gè)全局的斷網(wǎng)提示組件的顯示隱藏
// 關(guān)于斷網(wǎng)組件中的刷新重新獲取數(shù)據(jù),會(huì)在斷網(wǎng)組件中說(shuō)明
message.warn('網(wǎng)絡(luò)連接異常,請(qǐng)稍后再試!');
}
});
}
/**
* http握手錯(cuò)誤
* @param res 響應(yīng)回調(diào),根據(jù)不同響應(yīng)進(jìn)行不同操作
*/
private errorHandle(res: any) {
// 狀態(tài)碼判斷
switch (res.status) {
case 401:
break;
case 403:
break;
case 404:
message.warn('請(qǐng)求的資源不存在');
break;
default:
message.warn('連接錯(cuò)誤');
}
}
}
http.ts(http封裝,自己根據(jù)實(shí)際情況處理)
/**
* @author keiferju
* @time 2019-08-29 12:57
* @title http請(qǐng)求封裝
* @desc
*
*/
import {Interceptors} from '@/service/interceptors';
import {message, Modal} from 'ant-design-vue'; // 彈吐司
import router from '../router';
export class HttpService {
public axios: any;
public modal: any;
constructor() {
// 獲取axios實(shí)例
this.axios = new Interceptors().getInterceptors();
}
/**
* get請(qǐng)求
* @param params 參數(shù)
* @param jwt 是否token校驗(yàn)
* @param modulename 模塊
* @param operation 接口
* @param flag 標(biāo)記
* @param verson 版本,默認(rèn)1.0.0
* @param service 服務(wù),默認(rèn)services
*/
public getData(params: object, jwt: boolean, modulename: string, operation: string,
flag: string, verson = '1.0.0', service = 'services') {
const url = service + '/' + verson + '/' + modulename + '/' + operation;
const body = {
parameter: {
data: params,
tag: flag,
},
};
return new Promise((resolve, reject) => {
this.axios.get(url, {
params: body,
headers: {isJwt: jwt},
}).then((res) => {
this.resultHandle(res, resolve);
}).catch((err) => {
reject(err.message);
});
});
}
/**
* post請(qǐng)求
* @param params 參數(shù)
* @param jwt 是否token校驗(yàn)
* @param modulename 模塊
* @param operation 接口
* @param flag 標(biāo)記
* @param verson 版本,默認(rèn)1.0.0
* @param service 服務(wù),默認(rèn)services
*/
public postData(params: object, jwt: boolean, modulename: string, operation: string,
flag: string, verson = '1.0.0', service = 'services') {
const url = service + '/' + verson + '/' + modulename + '/' + operation;
const body = {
data: params,
tag: flag,
};
return new Promise((resolve, reject) => {
this.axios.post(url, body, {
headers: {isJwt: jwt},
}).then((res) => {
this.resultHandle(res, resolve);
}).catch((err) => {
reject(err.message);
});
});
}
/**
*
* @param res
* @param resolve
*/
public resultHandle(res: any, resolve) {
if (res.status > 0) {
resolve(res.data);
} else {
this.errorHandle(res);
}
}
/**
* 服務(wù)端狀態(tài)處理,例如中斷性異常,退出異常等等(與攔截器http握手狀態(tài)注意區(qū)分,一般都能分清楚吧)
* @param res
*/
public errorHandle(res: any) {
message.warn(res.msg); // 統(tǒng)一談服務(wù)端提示,我們提示統(tǒng)一由服務(wù)端提供
// 狀態(tài)碼判斷
switch (res.status) {
case -102:
break;
case -152:
break;
default:
// console.log(other);
}
}
}
3. 掛載
我們定義好攔截器,那么就得把他掛載全局,能讓我們方便使用.
main.ts
import Vue from 'vue';
import App from './App.vue';
import HighchartsVue from 'highcharts-vue';
Vue.config.productionTip = false;
Vue.prototype.$httpService = new HttpService(); // 掛載服務(wù)
new Vue({
router,
render: (h) => h(App),
}).$mount('#app');
4. ts橋連(也不知道怎么稱(chēng)呼,自己從ng時(shí)就一直這么稱(chēng)呼)
行完上一步一定會(huì)發(fā)現(xiàn)報(bào)錯(cuò)啊,$httpService是個(gè)啥,不存在啊,這是因?yàn)閠s的特性導(dǎo)致.
main.ts的同級(jí)目錄創(chuàng)建一個(gè)xx.d.ts文件.
import {HttpService} from './service/http';
declare module 'vue/types/vue' {
interface Vue {
$httpService: HttpService;
}
}
5. 使用
在其它組件中使用,直接用this調(diào)用,不用再去引用,但是小心在某個(gè)this指向變了的回調(diào)中使用時(shí)找不到,至于怎么怎么解決應(yīng)該都懂.
this.$httpService.postData({}, true, 'execute', 'xxx', 'tag').then((result) => {
// doing
}, (error) => {
console.log(error);
});
最后:這是在ts下的封裝,js的話(huà)更簡(jiǎn)單點(diǎn),甚至應(yīng)該會(huì)更簡(jiǎn)單點(diǎn)(會(huì)少一些步驟,網(wǎng)上教程應(yīng)該很多).掛載http工具的方式平時(shí)也適合我們定義全局工具類(lèi)或者服務(wù).
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
后臺(tái)獲取ZTREE選中節(jié)點(diǎn)的方法
這篇文章主要介紹了后臺(tái)獲取ZTREE選中節(jié)點(diǎn)的方法,實(shí)例分析了ZTREE中g(shù)etZTreeObj方法與getCheckedNodes方法的使用技巧,需要的朋友可以參考下2015-02-02
uniapp自定義網(wǎng)絡(luò)檢測(cè)組件項(xiàng)目實(shí)戰(zhàn)總結(jié)分析
這篇文章主要為大家介紹了uniapp自定義網(wǎng)絡(luò)檢測(cè)組件項(xiàng)目實(shí)戰(zhàn)總結(jié)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
js實(shí)現(xiàn)左側(cè)網(wǎng)頁(yè)tab滑動(dòng)門(mén)效果代碼
這篇文章主要介紹了js實(shí)現(xiàn)左側(cè)網(wǎng)頁(yè)tab滑動(dòng)門(mén)效果代碼,涉及JavaScript頁(yè)面元素的遍歷及元素屬性動(dòng)態(tài)切換的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
Javascript-Mozilla和IE中的一個(gè)函數(shù)直接量的問(wèn)題
Javascript-Mozilla和IE中的一個(gè)函數(shù)直接量的問(wèn)題...2007-01-01
JavaScript實(shí)現(xiàn)事件的中斷傳播和行為阻止方法示例
這篇文章主要給大家介紹了利用JavaScript實(shí)現(xiàn)事件的中斷傳播和行為阻止的方法示例,文中給出了詳細(xì)的介紹和示例代碼,相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-01-01
Ionic實(shí)現(xiàn)頁(yè)面下拉刷新(ion-refresher)功能代碼
這篇文章主要介紹了使用Ionic實(shí)現(xiàn)頁(yè)面下拉刷新(ion-refresher)功能的代碼,感興趣的朋友一起看看吧2016-06-06
JS實(shí)現(xiàn)Fisheye效果動(dòng)感放大菜單代碼
這篇文章主要介紹了JS實(shí)現(xiàn)Fisheye效果動(dòng)感放大菜單代碼,涉及JavaScript事假監(jiān)聽(tīng)機(jī)制及定時(shí)函數(shù)等相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10
ionic實(shí)現(xiàn)滑動(dòng)的三種方式
這篇文章主要為大家詳細(xì)介紹了ionic實(shí)現(xiàn)滑動(dòng)的三種方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08

