基于 Vue 和 Axios 的接口复用方案

以下是一个基于 VueAxios 的接口复用方案,结合全局配置、拦截器和模块化管理,实现高复用性和可维护性。方案分为 基础配置拦截器封装接口模块化组件调用 四部分,并附详细代码示例。


1. 基础配置(Axios 实例化)

创建独立的 axios 实例,配置全局参数(如基础 URL、超时时间),便于统一管理。

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

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API || '/api', // 环境变量配置[2](@ref)[6](@ref)
  timeout: 10000, // 超时时间
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  }
});

export default service;

2. 拦截器封装

通过请求 / 响应拦截器统一处理 Token 添加错误码全局提示

请求拦截器

// src/utils/request.js
service.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`; // 自动添加 Token[3](@ref)[9](@ref)
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

响应拦截器

service.interceptors.response.use(
  response => {
    const res = response.data;
    if (res.code === 200) {
      return res.data; // 提取核心数据[9](@ref)
    } else {
      console.error(res.message || '请求失败');
      return Promise.reject(res);
    }
  },
  error => {
    if (error.response) {
      switch (error.response.status) {
        case 401:
          console.error('未授权,跳转登录页');
          break;
        case 500:
          console.error('服务器错误');
          break;
        default:
          console.error('网络错误');
      }
    }
    return Promise.reject(error);
  }
);

3. 接口模块化管理

按功能模块拆分接口,避免散落在组件中。

用户模块示例

// src/api/user.js
import request from '@/utils/request';

export function login(data) {
  return request({
    url: '/user/login',
    method: 'post',
    data
  });
}

export function getUserInfo() {
  return request({
    url: '/user/info',
    method: 'get'
  });
}

商品模块示例

// src/api/product.js
import request from '@/utils/request';

export function getProductList(params) {
  return request({
    url: '/product/list',
    method: 'get',
    params
  });
}

4. 组件中调用接口

在 Vue 组件中引入模块化接口,简化调用逻辑。

登录组件示例

<template>
  <button @click="handleLogin">登录</button>
</template>

<script>
import { login } from '@/api/user';

export default {
  methods: {
    async handleLogin() {
      try {
        const res = await login({ username: 'admin', password: '123456' });
        console.log('登录成功', res);
      } catch (error) {
        console.error('登录失败', error);
      }
    }
  }
};
</script>

商品列表组件示例

<template>
  <ul>
    <li v-for="item in productList" :key="item.id">{{ item.name }}</li>
  </ul>
</template>

<script>
import { getProductList } from '@/api/product';

export default {
  data() {
    return {
      productList: []
    };
  },
  async created() {
    this.productList = await getProductList({ page: 1 });
  }
};
</script>

5. 高级复用技巧

动态 API 前缀

通过环境变量区分开发 / 生产环境:

// .env.development
VUE_APP_BASE_API = ' http://dev-api.example.com '

// .env.production
VUE_APP_BASE_API = ' http://prod-api.example.com '

请求取消

防止重复提交:

const pendingRequests = new Map();

service.interceptors.request.use(config => {
  const requestKey = `${config.url}-${config.method}`;
  if (pendingRequests.has(requestKey)) {
    pendingRequests.get(requestKey).cancel('重复请求');
  }
  const cancelToken = new axios.CancelToken(cancel => {
    pendingRequests.set(requestKey, { cancel });
  });
  config.cancelToken = cancelToken;
  return config;
});

总结

  • 复用性:通过全局配置和模块化接口,避免重复代码。

  • 可维护性:拦截器统一处理逻辑,便于后期调整。

  • 安全性:自动管理 Token 和错误状态码。

完整代码结构参考:

src/
├── api/
│   ├── user.js       # 用户接口模块
│   └── product.js    # 商品接口模块
├── utils/
│   └── request.js    # Axios 封装
└── views/
    └── Login.vue     # 组件调用示例


基于 Vue 和 Axios 的接口复用方案
https://uniomo.com/archives/wei-ming-ming-wen-zhang-I1ibvrlL
作者
雨落秋垣
发布于
2025年09月07日
许可协议