Vue项目中Axios封装、拦截器配置与并发请求处理详解

作者:雾松

时间:2026-10-24

浏览:627

本文详细介绍在Vue项目中如何规范封装axios,包括基础配置、接口分层管理及拦截器的使用。重点讲解如何通过拦截器判断并处理特定请求,以及如何利用Promise.all或axios.all实现多个并发请求的加载状态控制,附带跨域处理与POST序列化建议。

文章目录

Axios简介与特性

Axios是一个基于Promise的HTTP客户端,既适用于浏览器环境,也支持Node.js运行环境。自Vue 2.0发布后,官方不再维护vue-resource,转而推荐使用axios,因此本项目采用axios作为网络请求库。其主要功能特性包括:在浏览器中发送XMLHttpRequests请求,在Node.js中发送http请求,支持Promise API,提供请求和响应的拦截机制,支持请求和响应数据的转换,支持取消请求,自动将JSON数据转换为JavaScript对象,以及客户端自动防护免受CSRF/XSRF(跨站请求伪造)攻击。

Axios封装与目录结构

封装使用策略

建议将代码拆分为三个独立文件以优化结构。

目录结构建议如下:在src目录下创建service文件夹,其中包含axios.js(负责axios配置、拦截器及统一url处理)、index.js(定义接口方法,调用api模块,供页面级组件调用);在api文件夹下创建index.js(定义具体API方法,调用后端提供的接口,供service层的接口方法调用)。

基础配置与接口调用

axios.js基本配置


'use strict';
import axios from 'axios';

// 自动识别接口使用开发环境地址(开发环境地址做了 proxyTable 代理,故设置为空)或线上地址
axios.defaults.baseURL = process.env.NODE_ENV === 'production' ? process.env.API_ROOT : '';
// 开发环境直接打包测试
// axios.defaults.baseURL = '';

axios.interceptors.request.use(config => {
 return config;
}, error => {
 console.log(error);
 return Promise.reject(error);
});

axios.interceptors.response.use(res => {
 const apiRes = res.data;
 return apiRes;
}, async error => {
 console.dir(error);
 return Promise.reject(error);
});

export default axios;

api/index.js 调用后端提供的接口
import Ax from '@/service/axios';
import qs from 'qs';

export default {
 fetchBlog (reqData) {
  return Ax.get('/krryblog/blog/getBlog', {params: reqData});
 },
 addBlog (reqData) {
  return Ax.post('/krryblog/blog/addBlog', qs.stringify(reqData));
 },
 updateBlog (reqData) {
  return Ax.post('/krryblog/blog/updateBlog', qs.stringify(reqData));
 },
 deleteBlogCover (id, reqData) {
  return Ax.post(`/krryblog/blog/deleteBlogCover/${id}`, qs.stringify(reqData));
 },
};

index.js接口方法(调用api)


import Api from './api';

export async function getBlog(reqData) {
 let res = await Api.fetchBlog(reqData);
 return res;
},
export async function addBlog (reqData) {
 let res = await Api.addBlog(reqData);
 return res;
},
export async function updateBlog (reqData) {
 let res = await Api.updateBlog(reqData);
 return res;
},
export async function deleteBlogCover (id, reqData) {
 let res = await Api.deleteBlogCover(id, reqData);
 return res;
},

页面调用示例

完成上述配置后,即可在页面组件中直接调用封装好的接口方法。


import { getBlog } from '@/service'
export default {
 data() {
  return {
   tableData: [],
   pageIndex: 1,
   pageSize: 9
  }
 },
 created() {
  this.getList();
 },
 methods: {
  async getList() {
   let { result } = await getBlog({
    pageIndex: this.pageIndex,
    pageSize: this.pageSize
   });
  this.tableData = result.data;
 },
}

并发请求处理

接下来介绍如何在axios中执行多个并发请求。


async getList() {
 let resArr = []
 for (let val of this.arrId) {
  // push 请求
  resArr.push(queryPropertyValue({ id: val }))
 }
 this.tableData = []
 Promise.all(resArr).then(res => {
  for (let val of res) {
   let vals = val.result.propertyValues
   // 每个请求的结果 push 到 tableData
   vals.forEach(item => this.tableData.push(item))
  }
 })
},

或者直接在axios代码中编写Promise.all逻辑。


// 根据 id 获取某一条商品数据
let getDetail = (id)=>{
 return axios.get(`/detail?bid=${id}`);
}

// 检测登录的用户是否将此商品加入购物车
let detectCar = (shopId,userId)=>{
 return axios.get(`/detectCar?shopId=${shopId}&userId=${userId}`);
}

// 获取一条商品数据、并且检测是否加入购物车
let getDeAll = (shopId,userId)=>{
 axios.all([
  getDetail(shopId),
  detectCar(shopId,userId)
 ]).then(axios.spread((resDetail, resCar)=>{
  // 两个请求现已完成
  // 打印两个请求的响应值 
  console.log(resDetail);
  console.log(resCar);
 }));
}

以下是axios实例方法的说明。


axios#request(config)
axios#get(url [,config])
axios#delete(url [,config])
axios#head(url [,config])
axios#post(url [,data [,config]])
axios#put(url [,data [,config]])
axios#patch(url [,data [,config]])

关于请求配置:url是必需参数,若未指定method,请求将默认为GET。

拦截器与特定请求处理

axios拦截特定请求的处理方式

业务场景中常遇到需要拦截某些特定请求的情况,以便在这些特定请求发生时,页面采取或不采取相应的变化。

研究axios的request统一拦截方法:axios.interceptors.request.use(function (config) {})

拦截器接收的参数config结构如下:

通过观察config.url可以发现,它即为请求接口的地址。例如,若URL为“/getClassify”,则“getClassify”即为该请求的方法名。因此,可以通过解析字符串来判断是否为特定请求,从而执行相应的逻辑变化。


axios.interceptors.request.use(config => {
 // 判断请求是否是 getClassify,如果是 getClassify,不加载 LoadingBar
 let url = config.url;
 if (url.split('/').pop() === 'getClassify') {
  flag = false;
 } else {
  iView.LoadingBar.start();
  flag = true;
 }
 return config;
}, error => {
 console.log(error);
 return Promise.reject(error);
});

请求加载状态与Post问题

如何判断所有请求加载完毕


let reqNum = 0
axios.interceptors.request.use(function (config) {
 // 在请求发出之前进行一些操作,每次发出请求就 reqNum++
 reqNum++
 _bus.$emit('showloading')
 return config
}

axios.interceptors.response.use(response => {
 // 接受请求后 reqNum--,判断请求所有请求是否完成
 reqNum--
 if (reqNum <= 0) {
  _bus.$emit('closeLoading')
 } else {
  _bus.$emit('showloading')
 }
})

关于axios的post请求相关问题

如果遇到post请求的跨域问题,可以在webpack配置文件中设置proxyTable来处理跨域。参考链接:https://ainyi.com/27。此外,post请求携带参数时,需要进行序列化操作,使用qs.stringify(reqData)处理数据。


saveNormalAds (reqData) {
 return Ax.post('/index.php?krry', qs.stringify(reqData));
},

总结

以上介绍了在Vue项目中详解axios的封装使用、拦截特定请求以及判断所有请求加载完毕的方法,希望对大家有所帮助。如有任何疑问,欢迎留言,作者会及时回复。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章