Vue 3 中基于 Axios 的请求封装实践

1. 引言

在 Vue 3 项目中,封装请求模块是提高代码复用性和可维护性的重要步骤。通过封装 Axios,我们可以统一处理请求头、Token、错误处理和数据加密等逻辑,从而避免重复代码并提升开发效率。

2. 封装 Axios 请求模块

以下是一个完整的 Axios 请求封装示例,适用于 Vue 3 项目:

request.ts:

import axios from 'axios'
import { CURRENT_CONFIG } from './config'
import { message } from 'ant-design-vue'
import router from '/@/router'
import { ELocalStorageKey, ERouterName, EUserType } from '/@/types/enums'
import Cookies from 'js-cookie'
export * from './type'

const REQUEST_ID = 'X-Request-Id'
function getAuthToken () {
  return Cookies.get(ELocalStorageKey.Token) || new Date().getTime()
}


const instance = axios.create({
  headers: {
    'Content-Type': 'application/json',
  },
})

instance.interceptors.request.use(
  config => {
    config.headers[ELocalStorageKey.Token] = getAuthToken()
    config.baseURL = CURRENT_CONFIG.baseURL
    return config
  },
  error => {
    return Promise.reject(error)
  },
)

instance.interceptors.response.use(
  response => {  
    if (response.data.code && response.data.code !== 0) {
      if (response.data.message == '请重新登录') {
        setTimeout(() => {
          router.push(ERouterName.PROJECT)
          return
        }, 1000);
      }
    }
    return response
  },
  err => {
    
    const requestId = err?.config?.headers && err?.config?.headers[REQUEST_ID]
    if (requestId) {
      console.info(REQUEST_ID, ':', requestId)
    }

    let description = '-'
    if (err.response?.data && err.response.data.message) {
      description = err.response.data.message
    }
    if (err.response?.data && err.response.data.result) {
      description = err.response.data.result.message
    }
    if (!err.response || !err.response.status) {
      message.error('网络异常,请检查服务,然后重试')
      return
    }
    if (err.response?.status !== 200) {
      message.error(`ERROR_CODE: ${err.response?.status}`)
    }
    if (err.response?.status === 401) {
      console.error(err.response)
      Cookies.remove(ELocalStorageKey.Token);
      Cookies.remove(ELocalStorageKey.Username);
      router.push(ERouterName.PROJECT)
    }

    return Promise.reject(err)
  },
)

export default instance
3. 封装的关键点
  1. 统一配置:通过 Axios 实例设置 baseURL 和超时时间。

  2. Token 管理:在请求拦截器中动态添加 Token。

  3. 错误处理:在响应拦截器中统一处理错误,避免在组件中重复编写错误处理逻辑。

  4. 请求 ID:为每个请求添加唯一 ID,便于调试。

  5. 跳转逻辑:根据错误类型(如 401)清除 Token 并跳转到登录页面。

4. 使用封装的请求模块

yourFile.ts:

import request, { IWorkspaceResponse } from '/@/api/http/request'
//GET
export const getYourInterface = async (body: elementGroupsReq): Promise<IWorkspaceResponse<any>> => {
  const url = `${PREFIX}/yourInterfaceUrl/`+ your_id + '/element-groups'
  const result = await request.get(url, body)
  return result.data
}
//POST
export const postYourInterface = async (pid: string, body: PostElementsBody): Promise<IWorkspaceResponse<{ id: string }>> => {
  const url = `${PREFIX}/InterfaceUrl/` + your_id + `/element-groups/${pid}/elements`
  const result = await request.post(url, body)
  return result.data
}

vue文件:

import {postYourInterface ,getYourInterface } from '/@/api/layer'
async function getYourInterfaceData  (type?: string) {
  const result = await getYourInterface ({
    yourId: '',
    isDistributed: true
  })
  mapLayers.value = result.data
}

async function postYourInterfaceData(obj) {
  const req = await postYourInterface (参数,参数)
  mapLayers.value = req.data
}
5. 注意事项
  1. 跨域问题:如果遇到跨域问题,可以在后端配置 CORS 或通过代理解决。

  2. Token 刷新机制:如果需要支持 Token 刷新,可以在响应拦截器中捕获 401 状态码并自动刷新 Token。

  3. 环境变量:使用 import.meta.env 动态配置 API 地址。

6. 总结

通过封装 Axios,我们实现了一个高效、灵活且易于维护的请求模块。它不仅减少了重复代码,还提升了项目的整体质量。希望本文的示例能帮助你在 Vue 3 项目中更好地管理 HTTP 请求。

如果你有任何问题或建议,欢迎留言交流!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值