Vue项目实战:优雅封装Axios请求(含完整代码示例)

一、为什么要封装Axios?

在Vue项目中直接使用Axios存在以下问题:

  1. 多个组件重复编写相同的请求配置
  2. 缺乏统一的错误处理机制
  3. 难以维护和更新全局配置
  4. 无法快速切换不同环境接口地址

通过封装Axios可以实现:
✅ 统一管理接口地址
✅ 集中处理错误信息
✅ 添加全局Loading效果
✅ 简化组件中的使用方式
✅ 增强代码可维护性


二、完整封装实现步骤

1. 创建Axios实例

// src/utils/request.js
import axios from 'axios'

// 创建自定义实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // 从环境变量读取基础地址
  timeout: 15000 // 请求超时时间
})

2. 添加请求拦截器

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 在发送请求前做些什么
    if (store.getters.token) {
      config.headers['Authorization'] = `Bearer ${store.getters.token}`
    }
    return config
  },
  error => {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

3. 添加响应拦截器

// 响应拦截器
service.interceptors.response.use(
  response => {
    const res = response.data
    
    // 自定义状态码验证(根据后端约定)
    if (res.code !== 200) {
      ElMessage.error(res.message || 'Error')
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    // 处理HTTP网络错误
    let message = ''
    if (error && error.response) {
      switch (error.response.status) {
        case 401:
          message = "认证失败,请重新登录"
          break
        case 403:
          message = "当前操作没有权限"
          break
        case 404:
          message = "资源不存在"
          break
        default:
          message = "网络异常,请稍后重试"
      }
    }
    ElMessage.error(message)
    return Promise.reject(error)
  }
)

4. 封装通用请求方法

/**
 * 通用请求方法
 * @param {Object} options 请求配置
 */
function request(options) {
  return service({
    method: options.method || 'GET',
    url: options.url,
    data: options.data,
    params: options.params,
    ...options
  })
}

// 封装GET/POST快捷方法
export function get(url, params, options = {}) {
  return request({
    url,
    params,
    method: 'GET',
    ...options
  })
}

export function post(url, data, options = {}) {
  return request({
    url,
    data,
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      ...options.headers
    },
    ...options
  })
}

三、在Vue组件中使用

1. 发起请求

import { get, post } from '@/utils/request'

export default {
  methods: {
    // GET请求示例
    async fetchData() {
      try {
        const res = await get('/api/user/list', { page: 1 })
        console.log(res.data)
      } catch (error) {
        console.error(error)
      }
    },

    // POST请求示例
    async submitForm() {
      const data = { username: 'admin', password: '123456' }
      const res = await post('/api/login', data)
      console.log(res.token)
    }
  }
}

四、高级扩展技巧

1. 文件上传处理

export function uploadFile(url, file) {
  const formData = new FormData()
  formData.append('file', file)
  return post(url, formData, {
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  })
}

2. 添加全局Loading

let loadingInstance

service.interceptors.request.use(config => {
  loadingInstance = ElLoading.service({ fullscreen: true })
  return config
})

service.interceptors.response.use(response => {
  loadingInstance.close()
  return response
}, error => {
  loadingInstance.close()
  return Promise.reject(error)
})

3. 接口地址管理

创建单独的api配置文件:

// src/api/index.js
export default {
  user: {
    login: '/api/login',
    getInfo: '/api/user/info',
    list: '/api/user/list'
  },
  article: {
    create: '/api/article/create'
  }
}

五、项目结构建议

src/
├── api/          // 接口模块化管理
├── utils/
│   └── request.js // Axios封装文件
└── store/        // Vuex存储

六 、技术对比

下面是关于Fetch API、umi-request、jQuery.ajax和axios的对比表格:

Fetch APIumi-requestjQuery.ajaxaxios
技术基础基于Promise的现代浏览器API基于fetch的封装,提供统一API和请求层治理原生JavaScript中的XMLHttpRequest封装基于Promise的HTTP客户端,封装XMLHttpRequest
使用场景适用于现代浏览器环境,进行网络请求中台业务应用,提供统一请求库和接口治理各种Web开发中需要异步请求的场景浏览器和node.js环境,简化HTTP请求
语法简洁性语法简洁,支持链式调用和Promise风格简化了fetch的使用,提供统一API相对于原生XMLHttpRequest更简洁,但不如fetch简洁语法简洁,支持Promise和async/await
错误处理使用.catch()处理错误,对网络错误敏感提供统一的错误处理方式需要手动处理错误,如请求超时、网络错误等提供统一的错误处理方式,支持Promise的.catch()
请求与响应支持请求和响应对象,可自定义请求头和请求体支持请求和响应对象,提供请求超时、缓存等内置功能支持请求和响应对象,可自定义请求头和请求体支持请求和响应对象,可自定义请求头和请求体
跨域请求支持跨域请求,但需服务器支持CORS支持跨域请求,但需服务器支持CORS支持跨域请求,但需服务器支持CORS支持跨域请求,但需服务器支持CORS
自动解析JSON默认情况下,响应数据会被自动解析为JSON对象提供自动解析JSON的功能需要手动解析JSON数据自动转换JSON数据,无需手动解析
依赖项无需额外库,浏览器原生支持基于fetch的封装,需安装umi-request需要引入jQuery库需安装axios库
功能丰富性提供基本的网络请求功能提供请求层治理、统一接口文档等功能提供基本的Ajax请求功能提供请求和响应拦截、取消请求等功能
社区支持广泛使用的现代API,社区支持良好适用于特定业务场景,社区支持可能因业务而异jQuery库广泛使用,Ajax功能也有良好支持流行的HTTP客户端,社区支持良好

归纳

  • Fetch API:适合现代浏览器环境,语法简洁,支持Promise风格,但功能相对基础,需要手动处理一些高级功能。
  • umi-request:基于fetch的封装,提供统一API和请求层治理,适用于中台业务应用,简化了fetch的使用,并提供了额外的内置功能。
  • jQuery.ajax:依赖于jQuery库,提供了更简洁的Ajax请求方式,但引入jQuery库可能会增加项目体积。
  • axios:功能丰富,支持Promise和async/await,适用于大型项目和复杂场景,提供了请求和响应拦截、取消请求等高级功能。

选择哪种技术取决于项目的需求、个人偏好以及项目的技术栈

七、总结

通过本文的封装方案,你可以获得:

  1. 统一的请求管理和错误处理
  2. 简洁的API调用方式
  3. 更好的代码维护性和扩展性
  4. 方便切换开发/生产环境

注意事项:

  1. 根据实际项目修改状态码判断逻辑
  2. 替换Element UI组件为你使用的UI库
  3. 完善TypeScript类型定义(推荐)

希望这篇实战指南能帮助你更好地组织Vue项目中的网络请求!如果有任何问题欢迎在评论区交流讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北辰alk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值