十分钟封装一个好用的axios步骤示例
目录
- 前言
- 想想需要做什么
- 通用能力
- 一步一步添加功能实现
- 正常请求该有的
- 请求响应拦截器
- 全局的loading配置
- 统一文件下载处理
- 使用
前言
项目启动会议上,大家各种出排期,各种出方案,大多数人的焦点都放在后端技术方案上,感情大家好像都觉得前期准备工作前端没啥好做的,不都有现成的脚手架吗?别人不都帮你做好了吗?我丢。。。。你说的好像不是没有道理,但是你真的用过官方的脚手架吗,除了帮我生成项目目录和打包编译之类的配置,还是有些框架层面的东西要我自己做的好吧。我不管我不管,你们都有启动准备排期,我他喵的也要!!
想想需要做什么
我争取到了一周的准备(划水摸鱼)时间,主要还是后端的大佬们牛批会争取啊,我只能和他们持平了,啊哈哈哈。先用vue-cli生成一个project吧,想想做些什么,想到以前的做项目通用请求能力封装这一块前期做的不太好,导致后面写起来一堆冗余代码,着实恶心到我了。那我必须前期把这个整整
通用能力
列一下我想要这个通用请求能达到什么样的效果
1.正常请求该有的(跨域携带cookie,token,超时设置)
2.请求响应拦截器
- 请求成功,业务状态码200,解析result给我,我不想一层一层的去判断拿数据
- http请求200, 业务状态码非200,说明逻辑判断这是不成功的,那就全局message提示服务端的报错
- http请求非200, 说明http请求都有问题,也全局message提示报错
- http请求或者业务状态码401都做注销操作
3.全局的loading配置, 默认开启,可配置关闭(由于后端的问题,经常会让前端加防抖节流或者loading不让用户在界面上疯狂乱点,行吧行吧,你们的问题前端帮你们解决,你的规矩就是规矩是吧)
4.统一文件下载处理 (不要再去各写各的下载了,你写一个,他写一个,一个项目就是这样整的跟屎一样)
一步一步添加功能实现
正常请求该有的
import axios, { AxiosInstance, AxiosRequestConfig } from "axios"; export const createAxiosByinterceptors = ( config?: AxiosRequestConfig ): AxiosInstance => { const instance = axios.create({ timeout: 1000, //超时配置 withCredentials: true, //跨域携带cookie ...config, // 自定义配置覆盖基本配置 }); return instance; };
请求响应拦截器
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, //超时配置 withCredentials: true, //跨域携带cookie ...config, // 自定义配置覆盖基本配置 }); // 添加请求拦截器 instance.interceptors.request.use( function (config: any) { // 在发送请求之前做些什么 console.log("config:", config); // config.headers.Authorization = vm.$Cookies.get("vue_admin_token"); return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); } ); // 添加响应拦截器 instance.interceptors.response.use( function (response) { // 对响应数据做点什么 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) { // 对响应错误做点什么 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 || "服务端异常"); 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请求数量等于1,弹出loading, 防止重复弹出 requestNum++; if (requestNum == 1) { loadingInstance = Loading.service({ text: "正在努力加载中....", background: "rgba(0, 0, 0, 0)", }); } }; const cancelLoading = () => { // 取消loading 如果pending请求数量等于0,关闭loading requestNum--; if (requestNum === 0) loadingInstance?.close(); }; export const createAxiosByinterceptors = ( config?: AxiosRequestConfig ): AxiosInstance => { const instance = axios.create({ timeout: 1000, //超时配置 withCredentials: true, //跨域携带cookie ...config, // 自定义配置覆盖基本配置 }); // 添加请求拦截器 instance.interceptors.request.use( function (config: any) { // 在发送请求之前做些什么 const { loading = true } = config; console.log("config:", config); // config.headers.Authorization = vm.$Cookies.get("vue_admin_token"); if (loading) addLoading(); return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); } ); // 添加响应拦截器 instance.interceptors.response.use( function (response) { // 对响应数据做点什么 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) { // 对响应错误做点什么 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 || "服务端异常"); return Promise.reject(error); } ); return instance; };
统一文件下载处理
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请求数量等于1,弹出loading, 防止重复弹出 requestNum++; if (requestNum == 1) { loadingInstance = Loading.service({ text: "正在努力加载中....", background: "rgba(0, 0, 0, 0)", }); } }; const cancelLoading = () => { // 取消loading 如果pending请求数量等于0,关闭loading requestNum--; if (requestNum === 0) loadingInstance?.close(); }; export const createAxiosByinterceptors = ( config?: AxiosRequestConfig ): AxiosInstance => { const instance = axios.create({ timeout: 1000, //超时配置 withCredentials: true, //跨域携带cookie ...config, // 自定义配置覆盖基本配置 }); // 添加请求拦截器 instance.interceptors.request.use( function (config: any) { // 在发送请求之前做些什么 const { loading = true } = config; console.log("config:", config); // config.headers.Authorization = vm.$Cookies.get("vue_admin_token"); if (loading) addLoading(); return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); } ); // 添加响应拦截器 instance.interceptors.response.use( function (response) { // 对响应数据做点什么 console.log("response:", response); const { loading = true } = response.config; if (loading) cancelLoading(); const { code, data, message } = response.data; // config设置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) { // 对响应错误做点什么 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 || "服务端异常"); return Promise.reject(error); } ); return instance; };
src/utils/index.ts import { Message } from "element-ui"; import { AxiosResponse } from "axios"; import vm from "@/main"; /** * 跳转登录 */ 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); // 成功 说明是普通对象数据 if (jsonData?.code !== 200) { Message.error(jsonData?.message ?? "请求失败"); reject(jsonData); } } catch (err) { // 解析成对象失败,说明是正常的文件流 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 }); // 不需要默认的全局loading效果可配置loading为false关闭 loading默认为true // 文件下载 export const exportGoods = (data: any) => request.post("/export", data, { responseType: "blob", });
完结撒花
以上就是十分钟省时又省力封装一个好用的axios步骤示例的详细内容,更多关于axios封装步骤的资料请关注我们其它相关文章!
赞 (0)