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