十分鐘封裝一個(gè)好用的axios步驟示例
前言
項(xiàng)目啟動(dòng)會(huì)議上,大家各種出排期,各種出方案,大多數(shù)人的焦點(diǎn)都放在后端技術(shù)方案上,感情大家好像都覺得前期準(zhǔn)備工作前端沒啥好做的,不都有現(xiàn)成的腳手架嗎?別人不都幫你做好了嗎?????我丟。。。。你說的好像不是沒有道理,但是你真的用過官方的腳手架嗎,除了幫我生成項(xiàng)目目錄和打包編譯之類的配置,還是有些框架層面的東西要我自己做的好吧。我不管我不管,你們都有啟動(dòng)準(zhǔn)備排期,我他喵的也要??!??
想想需要做什么
我爭(zhēng)取到了一周的準(zhǔn)備(劃水摸魚)時(shí)間,主要還是后端的大佬們牛批會(huì)爭(zhēng)取啊,我只能和他們持平了,啊哈哈哈。先用vue-cli生成一個(gè)project吧,想想做些什么,想到以前的做項(xiàng)目通用請(qǐng)求能力封裝這一塊前期做的不太好,導(dǎo)致后面寫起來一堆冗余代碼,著實(shí)惡心到我了。那我必須前期把這個(gè)整整????
通用能力
列一下我想要這個(gè)通用請(qǐng)求能達(dá)到什么樣的效果
1.正常請(qǐng)求該有的(跨域攜帶cookie,token,超時(shí)設(shè)置)
2.請(qǐng)求響應(yīng)攔截器
- 請(qǐng)求成功,業(yè)務(wù)狀態(tài)碼200,解析result給我,我不想一層一層的去判斷拿數(shù)據(jù)
- http請(qǐng)求200, 業(yè)務(wù)狀態(tài)碼非200,說明邏輯判斷這是不成功的,那就全局message提示服務(wù)端的報(bào)錯(cuò)
- http請(qǐng)求非200, 說明http請(qǐng)求都有問題,也全局message提示報(bào)錯(cuò)
- http請(qǐng)求或者業(yè)務(wù)狀態(tài)碼401都做注銷操作
3.全局的loading配置, 默認(rèn)開啟,可配置關(guān)閉(由于后端的問題,經(jīng)常會(huì)讓前端加防抖節(jié)流或者loading不讓用戶在界面上瘋狂亂點(diǎn),行吧行吧,你們的問題前端幫你們解決,你的規(guī)矩就是規(guī)矩是吧??)
4.統(tǒng)一文件下載處理 (不要再去各寫各的下載了,你寫一個(gè),他寫一個(gè),一個(gè)項(xiàng)目就是這樣整的跟屎一樣)
一步一步添加功能實(shí)現(xiàn)
正常請(qǐng)求該有的
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
export const createAxiosByinterceptors = (
config?: AxiosRequestConfig
): AxiosInstance => {
const instance = axios.create({
timeout: 1000, //超時(shí)配置
withCredentials: true, //跨域攜帶cookie
...config, // 自定義配置覆蓋基本配置
});
return instance;
};
請(qǐng)求響應(yīng)攔截器
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
import { Message } from "element-ui";
import { jumpLogin } from "@/utils";
export const createAxiosByinterceptors = (
config?: AxiosRequestConfig
): AxiosInstance => {
const instance = axios.create({
timeout: 1000, //超時(shí)配置
withCredentials: true, //跨域攜帶cookie
...config, // 自定義配置覆蓋基本配置
});
// 添加請(qǐng)求攔截器
instance.interceptors.request.use(
function (config: any) {
// 在發(fā)送請(qǐng)求之前做些什么
console.log("config:", config);
// config.headers.Authorization = vm.$Cookies.get("vue_admin_token");
return config;
},
function (error) {
// 對(duì)請(qǐng)求錯(cuò)誤做些什么
return Promise.reject(error);
}
);
// 添加響應(yīng)攔截器
instance.interceptors.response.use(
function (response) {
// 對(duì)響應(yīng)數(shù)據(jù)做點(diǎn)什么
console.log("response:", response);
const { code, data, message } = response.data;
if (code === 200) return data;
else if (code === 401) {
jumpLogin();
} else {
Message.error(message);
return Promise.reject(response.data);
}
},
function (error) {
// 對(duì)響應(yīng)錯(cuò)誤做點(diǎn)什么
console.log("error-response:", error.response);
console.log("error-config:", error.config);
console.log("error-request:", error.request);
if (error.response) {
if (error.response.status === 401) {
jumpLogin();
}
}
Message.error(error?.response?.data?.message || "服務(wù)端異常");
return Promise.reject(error);
}
);
return instance;
};
全局的loading配置
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
import { Message } from "element-ui";
import { jumpLogin } from "@/utils";
import { Loading } from "element-ui";
import { ElLoadingComponent } from "element-ui/types/loading";
// import vm from "@/main";
let loadingInstance: ElLoadingComponent | null = null;
let requestNum = 0;
const addLoading = () => {
// 增加loading 如果pending請(qǐng)求數(shù)量等于1,彈出loading, 防止重復(fù)彈出
requestNum++;
if (requestNum == 1) {
loadingInstance = Loading.service({
text: "正在努力加載中....",
background: "rgba(0, 0, 0, 0)",
});
}
};
const cancelLoading = () => {
// 取消loading 如果pending請(qǐng)求數(shù)量等于0,關(guān)閉loading
requestNum--;
if (requestNum === 0) loadingInstance?.close();
};
export const createAxiosByinterceptors = (
config?: AxiosRequestConfig
): AxiosInstance => {
const instance = axios.create({
timeout: 1000, //超時(shí)配置
withCredentials: true, //跨域攜帶cookie
...config, // 自定義配置覆蓋基本配置
});
// 添加請(qǐng)求攔截器
instance.interceptors.request.use(
function (config: any) {
// 在發(fā)送請(qǐng)求之前做些什么
const { loading = true } = config;
console.log("config:", config);
// config.headers.Authorization = vm.$Cookies.get("vue_admin_token");
if (loading) addLoading();
return config;
},
function (error) {
// 對(duì)請(qǐng)求錯(cuò)誤做些什么
return Promise.reject(error);
}
);
// 添加響應(yīng)攔截器
instance.interceptors.response.use(
function (response) {
// 對(duì)響應(yīng)數(shù)據(jù)做點(diǎn)什么
console.log("response:", response);
const { loading = true } = response.config;
if (loading) cancelLoading();
const { code, data, message } = response.data;
if (code === 200) return data;
else if (code === 401) {
jumpLogin();
} else {
Message.error(message);
return Promise.reject(response.data);
}
},
function (error) {
// 對(duì)響應(yīng)錯(cuò)誤做點(diǎn)什么
console.log("error-response:", error.response);
console.log("error-config:", error.config);
console.log("error-request:", error.request);
const { loading = true } = error.config;
if (loading) cancelLoading();
if (error.response) {
if (error.response.status === 401) {
jumpLogin();
}
}
Message.error(error?.response?.data?.message || "服務(wù)端異常");
return Promise.reject(error);
}
);
return instance;
};
統(tǒng)一文件下載處理
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
import { Message } from "element-ui";
import { jumpLogin, downloadFile } from "@/utils";
import { Loading } from "element-ui";
import { ElLoadingComponent } from "element-ui/types/loading";
// import vm from "@/main";
let loadingInstance: ElLoadingComponent | null = null;
let requestNum = 0;
const addLoading = () => {
// 增加loading 如果pending請(qǐng)求數(shù)量等于1,彈出loading, 防止重復(fù)彈出
requestNum++;
if (requestNum == 1) {
loadingInstance = Loading.service({
text: "正在努力加載中....",
background: "rgba(0, 0, 0, 0)",
});
}
};
const cancelLoading = () => {
// 取消loading 如果pending請(qǐng)求數(shù)量等于0,關(guān)閉loading
requestNum--;
if (requestNum === 0) loadingInstance?.close();
};
export const createAxiosByinterceptors = (
config?: AxiosRequestConfig
): AxiosInstance => {
const instance = axios.create({
timeout: 1000, //超時(shí)配置
withCredentials: true, //跨域攜帶cookie
...config, // 自定義配置覆蓋基本配置
});
// 添加請(qǐng)求攔截器
instance.interceptors.request.use(
function (config: any) {
// 在發(fā)送請(qǐng)求之前做些什么
const { loading = true } = config;
console.log("config:", config);
// config.headers.Authorization = vm.$Cookies.get("vue_admin_token");
if (loading) addLoading();
return config;
},
function (error) {
// 對(duì)請(qǐng)求錯(cuò)誤做些什么
return Promise.reject(error);
}
);
// 添加響應(yīng)攔截器
instance.interceptors.response.use(
function (response) {
// 對(duì)響應(yīng)數(shù)據(jù)做點(diǎn)什么
console.log("response:", response);
const { loading = true } = response.config;
if (loading) cancelLoading();
const { code, data, message } = response.data;
// config設(shè)置responseType為blob 處理文件下載
if (response.data instanceof Blob) {
return downloadFile(response);
} else {
if (code === 200) return data;
else if (code === 401) {
jumpLogin();
} else {
Message.error(message);
return Promise.reject(response.data);
}
}
},
function (error) {
// 對(duì)響應(yīng)錯(cuò)誤做點(diǎn)什么
console.log("error-response:", error.response);
console.log("error-config:", error.config);
console.log("error-request:", error.request);
const { loading = true } = error.config;
if (loading) cancelLoading();
if (error.response) {
if (error.response.status === 401) {
jumpLogin();
}
}
Message.error(error?.response?.data?.message || "服務(wù)端異常");
return Promise.reject(error);
}
);
return instance;
};
src/utils/index.ts
import { Message } from "element-ui";
import { AxiosResponse } from "axios";
import vm from "@/main";
/**
* 跳轉(zhuǎn)登錄
*/
export const jumpLogin = () => {
vm.$Cookies.remove("vue_admin_token");
vm.$router.push(`/login?redirect=${encodeURIComponent(vm.$route.fullPath)}`);
};
/**
* 下載文件
* @param response
* @returns
*/
export const downloadFile = (response: AxiosResponse) => {
console.log("response.data.type:", response.data.type);
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = function () {
try {
console.log("result:", this.result);
const jsonData = JSON.parse((this as any).result); // 成功 說明是普通對(duì)象數(shù)據(jù)
if (jsonData?.code !== 200) {
Message.error(jsonData?.message ?? "請(qǐng)求失敗");
reject(jsonData);
}
} catch (err) {
// 解析成對(duì)象失敗,說明是正常的文件流
const blob = new Blob([response.data]);
// 本地保存文件
const url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
const filename = response?.headers?.["content-disposition"]
?.split("filename*=")?.[1]
?.substr(7);
link.setAttribute("download", decodeURI(filename));
document.body.appendChild(link);
link.click();
resolve(response.data);
}
};
fileReader.readAsText(response.data);
});
};
使用
import { createAxiosByinterceptors } from "@/api/request";
const request = createAxiosByinterceptors({
baseURL: localhost:7007,
});
//lodaing配置
export const appList = (params: any): Promise<any> =>
request.get("/app", { params, loading: true }); // 不需要默認(rèn)的全局loading效果可配置loading為false關(guān)閉 loading默認(rèn)為true
// 文件下載
export const exportGoods = (data: any) =>
request.post("/export", data, {
responseType: "blob",
});
完結(jié)撒花??????
以上就是十分鐘省時(shí)又省力封裝一個(gè)好用的axios步驟示例的詳細(xì)內(nèi)容,更多關(guān)于axios封裝步驟的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue3 reactive定義的引用類型直接賦值導(dǎo)致數(shù)據(jù)失去響應(yīng)式問題
這篇文章主要介紹了vue3 reactive定義的引用類型直接賦值導(dǎo)致數(shù)據(jù)失去響應(yīng)式問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
Vue2.0 實(shí)現(xiàn)頁面緩存和不緩存的方式
今天小編就為大家分享一篇Vue2.0 實(shí)現(xiàn)頁面緩存和不緩存的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-11-11
vue中computed下使用箭頭函數(shù)會(huì)報(bào)錯(cuò)問題及解決
這篇文章主要介紹了vue中computed下使用箭頭函數(shù)會(huì)報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
vue項(xiàng)目接口域名動(dòng)態(tài)獲取操作
這篇文章主要介紹了vue項(xiàng)目接口域名動(dòng)態(tài)獲取操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Vue項(xiàng)目前端部署詳細(xì)步驟(nginx方式)
Nginx(engine x)是一個(gè)高性能的HTTP和反向代理web服務(wù)器,是部署前端項(xiàng)目的首選,這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目前端部署(nginx方式)的相關(guān)資料,需要的朋友可以參考下2023-09-09

