axios三层封装

为什么需要axios封装?

  1. 统一配置: 封装 Axios 允许你在一个集中的地方配置所有的 Axios 实例,比如基础 URL、超时时间、头部信息等。这样可以避免在每个请求中重复配置这些参数。

  2. 拦截器: 通过封装,你可以方便地添加请求拦截器和响应拦截器。这些拦截器可以在请求发送前或响应返回后统一处理数据,比如添加 token、检查响应状态码、统一错误处理等。

  3. 错误处理: 封装 Axios 可以让你在一个地方处理所有请求的错误,而不是在每个请求中单独处理。

  4. 代码复用: 如果你的项目中有很多相似的请求,你可以创建通用的请求方法来减少代码重复。

  5. 简化 API 调用: 封装可以让你创建更简洁的 API 调用接口,隐藏复杂的实现细节,使得调用 API 更加直观和简单。

  6. 支持 Promise 链 : 封装 Axios 可以让你轻松地返回 Promise 对象,这样可以在调用端使用 .then().catch() 方法处理异步请求。

初始代码

复制代码
// const handleLogin = async () => {
//   const res = await axios.post(
//     'http://172.18.208.1:5000/users/checkLogin',
//     qs.stringify(userInfo.value),
//   )
//   console.log(res);

//   const res1 = await axios.post(
//     url: 'http://172.18.208.1:5000/users/checkLogin',
//     mothod: 'get',
//     params: {
//       currentPage: 1,
//       pageSize:10
//     }
//     headers:{
//       Authorization:res.data.token
//     }
//     qs.stringify(userInfo.value),
//   )
//   console.log(res1)
// }

第一层封装背景

不封装直接使用是没有功能性问题的,但是如果直接使用会造成项目中充斥着大量重复代码,违背了diy原则,非常不利于维护,给项目带来了巨大的维护成本和风险,所以此时需要把请求中存在的重复代码进行第一次封装:把请求中重复的代码全部抽离出来放进request文件中,比如请求基路径,超时时间,请求拦截拦截器,请求头,异常处理,restful请求方法的公共代码

第一封装完请求代码

复制代码
const handleLogin = async () => {
  const res = await request.post('user/checkLogin', userInfo.value)
  console.log(res)
  const res1 = await request.get('user/list', {
    currentPage: 1,
    pageSize: 10,
  })
  console.log(res1)
}

resful文件

复制代码
import axios from 'axios'
import qs from 'qs'
const instance = axios.create({
  baseURL: 'http://127.0.0.1:5000', //请求的基路径
  timeout: 5000, //请求超时时间
})
// 请求拦截器 对前端的所有请求做统一处理,比如同一个所有请求添加请求
instance.interceptors.request.use(
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  (config: any) => {
    const token = JSON.parse(localStorage.getItem('t_k')!)
    if (token) {
      config.headers.Authorization = ''
    }
    return config
  },
  (err) => {
    console.log(err)
  },
)
// 响应拦截器 对后端的所有响应结果做统一处理,比如异常处理
instance.interceptors.response.use(
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  (response: any) => {
    // TODO 在这里判断接口异常处理逻辑(比如token失败后跳转登陆页面)
    return response.data
  },
  (err) => {
    // TODO 在这里判断接口网络异常处理逻辑(比如网络超时、网络错误)
    console.log(err)
  },
)
// 创建基于restful接口规范的异步请求方法
/**
 * get请求方法
 * @param url 请求的url地址
 * @param params 请求时携带的参数
 * @returns
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const get = async (url: string, params: any = {}) => {
  return await instance.get(url, { params })
}
/**
 * post请求
 * @param url 请求的是url地址 例如user/list
 * @param data 请求参数,eg:{ account: '', password: '' }
 * @returns
 */
const post = async (url: string, data: unknown) => {
  return await instance.post(url, qs.stringify(data))
}
/**
 * put请求
 * @param url 请求的url地址
 * @param data 提交的数据,将会被转成url编码的字符串
 * @returns
 */
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
const put = async (url: string, data: any) => {
  return await instance.put(url, qs.stringify(data))
}

/**
 * // delete请求
 * @param url 请求的url地址
 * @param params 可选
 * @returns
 */
const del = async (url: string, params: unknown) => {
  return await instance.delete(url, { params })
}

export default {
  get,
  post,
  put,
  del,
}

第二层封装背景

在项目中一般会有大量的异步请求代码,这写异步请求代码可能会在多个地方使用到,比较分散,同时这些异步请求的代码一把都应该是以模块来划分的,这样便于统一维护和管理

第二次封装完请求代码

复制代码
 const handleLogin = async () => {
  const res = await request.post('user/checkLogin', userInfo.value)
  console.log(res)
   const res1 = await request.get('user/list', {
    currentPage: 1,
    pageSize: 10,
  })
   console.log(res1)
 }

index文件

复制代码
import request from '@/utils/request'

interface LoginData {
  account: string
  password: string
}
/**
 * 登录接口异步方法
 * @param data 请求参数
 * @returns
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const fetchLogin = async (data: LoginData) => {
  // 这里可以写一些其他逻辑
  const res = await request.post('users/checkLogin', data)
  if (res.data.code === 0) {
    // 成功提示
  } else {
    // 失败提示
  }
  return res.data
}

第三层封装完的请求代码

复制代码
const handleLogin = async () => {
  const res = await fetchLogin(userInfo.value)
  console.log(res)
}

总结

第三层封装

第一层:把请求中的基路径,超时时间,拦截器等重复代码抽离到request中,遵循restful规范声明4个请求方式只暴露请求地址和请求参数

第二层:把所有的请求按照模块进行划分,把请求地址封装起来,把请求参数暴露出来

第三层:在vue组件中引入第二层封装,利用async / await 对异步代码同步化

相关推荐
南极星100513 分钟前
蓝桥杯JAVA--启蒙之路(十)class版本 模块
java·开发语言
未来之窗软件服务16 分钟前
未来之窗昭和仙君(六十五)Vue与跨地区多部门开发—东方仙盟练气
前端·javascript·vue.js·仙盟创梦ide·东方仙盟·昭和仙君
baidu_2474386117 分钟前
Android ViewModel定时任务
android·开发语言·javascript
嘿起屁儿整30 分钟前
面试点(网络层面)
前端·网络
Dev7z30 分钟前
基于 MATLAB 的铣削切削力建模与仿真
开发语言·matlab
不能隔夜的咖喱36 分钟前
牛客网刷题(2)
java·开发语言·算法
VT.馒头36 分钟前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
小天源43 分钟前
Error 1053 Error 1067 服务“启动后立即停止” Java / Python 程序无法后台运行 windows nssm注册器下载与报错处理
开发语言·windows·python·nssm·error 1053·error 1067
有位神秘人1 小时前
Android中Notification的使用详解
android·java·javascript
肉包_5111 小时前
两个数据库互锁,用全局变量互锁会偶发软件卡死
开发语言·数据库·c++