使用 Vue + Axios 构建与后端交互的高效接口调用方案
在 Vue 前端开发中,与后端接口的数据交互是非常核心的部分。而 Axios 是 Vue 项目中最常用的 HTTP 客户端,具备基于 Promise、拦截器、自定义实例等诸多优势。
本篇将深入介绍如何基于 Vue 搭配 Axios 构建一个高效、可维护、可复用的接口调用方案,并通过实战案例逐步拆解。
一、为什么选择 Axios?
Axios 相较于原生 fetch
或其他库的优势:
- 支持所有现代浏览器 + Node.js
- 自动转换 JSON 数据
- 请求/响应拦截器
- 支持请求取消
- 支持上传/下载进度监听
- 更友好的错误处理方式
二、项目中引入 Axios
在 Vue 3 + Vite 项目中安装 Axios:
bash
npm install axios
或使用 Yarn:
bash
yarn add axios
三、创建 Axios 实例(推荐)
在 src/utils/request.js
中统一配置 Axios 实例:
js
// src/utils/request.js
import axios from 'axios'
// 创建实例
const request = axios.create({
baseURL: '/api', // 可根据环境变量动态设置
timeout: 5000
})
// 请求拦截器
request.interceptors.request.use(
config => {
// 在发送请求之前可添加 token、语言设置等
const token = localStorage.getItem('token')
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
}
return config
},
error => Promise.reject(error)
)
// 响应拦截器
request.interceptors.response.use(
response => {
// 可根据后端接口结构统一处理
if (response.data.code !== 0) {
return Promise.reject(response.data.message)
}
return response.data.data
},
error => {
// 错误统一处理
console.error('网络请求错误:', error)
return Promise.reject(error)
}
)
export default request
四、封装 API 模块
将不同接口按模块组织,增强可维护性。
js
// src/api/user.js
import request from '@/utils/request'
export function login(data) {
return request.post('/user/login', data)
}
export function getUserInfo() {
return request.get('/user/info')
}
五、组件中调用接口
vue
<template>
<div>
<p v-if="user">你好,{{ user.name }}</p>
<button @click="fetchUser">获取用户信息</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { getUserInfo } from '@/api/user'
const user = ref(null)
const fetchUser = async () => {
try {
user.value = await getUserInfo()
} catch (err) {
console.error('获取失败:', err)
}
}
</script>
六、环境变量与动态 BaseURL 设置
在 .env.development
和 .env.production
中配置:
env
VITE_API_BASE_URL=https://api.example.com
Axios 实例中动态引用:
js
const request = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 5000
})
七、接口调用最佳实践
实践项 | 建议做法 |
---|---|
封装 axios 实例 | 集中管理请求配置 |
使用响应/请求拦截器 | 统一处理 token、错误提示、请求 loading 等 |
模块化接口函数 | 每个功能模块对应一个文件(如 user.js、post.js) |
异常处理统一封装 | 可封装 tryCatch() 或 useRequest() Hook |
接口参数校验 | 在请求前进行基本字段判断 |
自动重试/请求取消 | 可借助 axios-cancel-token、axios-retry 插件实现 |
八、封装 useRequest Hook(高级优化)
封装一个组合式 API 统一处理请求状态:
js
// src/hooks/useRequest.js
import { ref } from 'vue'
export function useRequest(apiFn) {
const loading = ref(false)
const error = ref(null)
const data = ref(null)
const run = async (...args) => {
loading.value = true
error.value = null
try {
data.value = await apiFn(...args)
} catch (err) {
error.value = err
} finally {
loading.value = false
}
}
return { loading, error, data, run }
}
组件中使用:
vue
<script setup>
import { useRequest } from '@/hooks/useRequest'
import { getUserInfo } from '@/api/user'
const { data: user, loading, error, run: fetchUser } = useRequest(getUserInfo)
fetchUser()
</script>
九、常见问题排查建议
-
跨域问题
使用 Vite 开发服务器的代理功能:
js// vite.config.js server: { proxy: { '/api': { target: 'https://api.example.com', changeOrigin: true, rewrite: path => path.replace(/^\/api/, '') } } }
-
响应为 null 或 undefined
检查拦截器中是否错误地 return 了
response.data
而不是response.data.data
-
token 失效未重定向登录
可在响应拦截器中判断状态码为 401 后跳转:
jsif (response.status === 401) { window.location.href = '/login' }
十、总结
通过 Axios 与 Vue 的组合使用,我们不仅能够实现基础的请求功能,还可以构建出统一化、模块化、易维护的接口调用架构。更进一步地,你还可以结合 Pinia/Vuex 管理数据、搭配组合式函数封装 Hook,打造属于你团队的最佳实践规范。