Vue与服务器交互的主力方案是axios,其次是原生fetch,两者各有适用场景。 如果你正在开发Vue 2或Vue 3项目,axios是多数团队的默认选择;如果追求零依赖、轻量级,fetch也完全够用,本文从选型、封装、跨域到超时处理,把Vue请求后端的完整链路讲清楚。
vue axios与fetch的区别:该选谁
先给结论:axios更像一位经验丰富的老司机,帮你把路上的坑都提前填平;fetch则是轻骑兵,简洁但需要自己照顾细节,据第三方调研机构统计,在前端HTTP库的使用率中,axios长期排名第一,行业共识认为,axios的生态稳定性是它至今仍被广泛使用的主要原因。
axios的优势
axios基于XMLHttpRequest封装,在浏览器和Node.js环境都能跑,它有几个让人省心的特性:
- 拦截器机制:请求和响应都能统一处理,比如携带token、统一错误提示。
- 请求取消:用AbortController或者内部cancel token,避免组件卸载后还在更新状态。
- 自动JSON转换:发对象会自动序列化,响应也会自动parse。
- 超时配置:
timeout字段一行搞定。
fetch的原生魅力和短板
fetch是浏览器原生API,不需要安装任何包,写法简洁,基于Promise,配合async/await用起来很舒服,但它的短板同样明显:
- 响应状态码不会reject:400、500不会走catch,你得手动检查
response.ok。 - 默认不带cookie:需要手动设置
credentials: 'include'才能跨域携带会话。 - 没有超时机制:必须借助AbortController来模拟,代码稍微啰嗦。
- 拦截器?不存在的:要自己封装请求函数。
选型对比表
| 维度 | axios | fetch |
|---|---|---|
| 拦截器 | 内置,请求响应都有 | 无,需自行封装 |
| 超时控制 | 内置timeout | 需AbortController模拟 |
| 错误处理 | 网络/HTTP错误统一走catch | 仅网络错误走catch |
| 依赖体积 |
会额外增加几十KB | 原生,零体积 |
| 适用复杂度 | 中大型项目 | 简单场景 |
vue3请求服务器数据用哪种方式更稳
Vue3普及后,大家讨论服务器交互方式的频率明显变高,除了axios和fetch,组合式API还催生了更多工具选择。
组合式API下的请求写法
在Vue3里,通常把请求放进setup或<script setup>中,你可以把axios请求封装成一个自定义组合函数:
// useApi.js
import { ref } from 'vue'
import axios from 'axios'
export function useApi(url) {
const data = ref(null)
const loading = ref(false)
const error = ref(null)
async function fetchData() {
loading.value = true
try {
const res = await axios.get(url)
data.value = res.data
} catch (e) {
error.value = e
} finally {
loading.value = false
}
}
fetchData()
return { data, loading, error }
}
这段代码展示了怎么把请求逻辑从组件里抽离出来,复用性更高,也方便在多个组件里共享同一套loading和error管理。
配合Pinia管理请求状态
当多个组件共享同一份服务器数据时,直接用Pinia store来保存请求结果,避免重复发请求,业界常见做法是:
- 在store的action里调用axios或fetch
- 用loading标志控制UI状态
- 组件里只通过
storeToRefs拿数据
这样不同页面切换时,数据还能留在内存里,减少无谓的服务器请求。
更现代的TanStack Query
如果你厌烦了手动维护loading、error、过期时间,业内专家指出,TanStack Query(原Vue Query)正被越来越多Vue3项目采纳,它把服务器状态和客户端状态彻底分离,内置缓存、重试、失效更新等能力,对于数据交互复杂的项目,它比单独用axios更能提升开发效率。
vue封装axios拦截器的完整步骤
拦截器是axios相对fetch最核心的优势,封装得好不好,直接决定项目里请求代码的整洁度。
第一步:创建axios实例
// request.js
import axios from 'axios'
const service = axios.create({
baseURL: import.meta.env.VITE_API_BASE,
timeout: 15000
})

把baseURL放到环境变量里,不同环境切换更方便,也避免在代码里写死地址。
第二步:请求拦截器
在请求发出前做三件常规事:
- 从
localStorage或Pinia里拿token,塞进Authorization头 - 统一加公共参数,比如时间戳防缓存
- 开启loading动画
service.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
第三步:响应拦截器
响应拦截器负责统一处理业务状态码,后端一般返回{ code: 200, data: ... }这种包裹结构。
业务码与HTTP错误码的分开处理
- 如果code为200,直接返回
response.data - 如果code为401,跳转登录页
- 其他错误码,用UI库弹出提示
service.interceptors.response.use(
res => {
if (res.data.code === 200) return res.data
if (res.data.code === 401) {
window.location.href = '/login'
return Promise.reject(new Error('未登录'))
}
ElMessage.error(res.data.msg)
return Promise.reject(new Error(res.data.msg))
},
err => {
ElMessage.error(err.message)
return Promise.reject(err)
}
)
这样封装之后,页面里的请求代码就只剩业务逻辑,不需要关心公共处理。
vue与后端交互遇到跨域问题怎么办
说到与服务器交互,跨域几乎是绕不开的坎,前端跑在localhost:3000,后端在localhost:8080,浏览器直接拦你。
开发环境用Vite代理
在vite.config.js里配置proxy,把请求转发到目标服务器:
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: p => p.replace(/^/api/, '')
}
}
}
}
这样前端请求/api/user,Vite会把它转发到http://localhost:8080/user,浏览器只看得到同源请求,跨域就消失了。
生产环境用Nginx反向代理

部署时前端的静态资源通常放在Nginx里,同样配置一层反向代理:
location /api/ {
proxy_pass http://后端服务器地址/;
}
如果后端允许,设置CORS响应头Access-Control-Allow-Origin也是通用做法,多数情况下,推荐Nginx代理,因为它对后端代码零侵入,管理起来也更集中。
vue请求接口超时设置与错误提示
请求挂起是最影响用户体验的问题之一,axios和fetch各有各的超时处理方式。
axios的timeout配置
axios在实例或单次请求里直接配置timeout: 15000,单位毫秒,超时后会触发错误,随后响应拦截器的错误分支会提示“请求超时,请重试”,关键是设置一个合理的值,比如普通接口用10秒,上传接口可以单独放宽到60秒。
fetch用AbortController模拟超时
const controller = new AbortController()
const timer = setTimeout(() => controller.abort(), 10000)
try {
const res = await fetch('/api/data', { signal: controller.signal })
clearTimeout(timer)
} catch (err) {
if (err.name === 'AbortError') {
console.log('请求超时')
}
}
这个方法在原生场景下是标准解法,如果你用的是axios,内部已经处理过了,不需要手写。
关于vue与服务器交互的常见疑问
vue项目一定要用axios吗?
不是,小项目或追求轻量化,fetch完全够用,但axios提供的拦截器和错误处理生态,能让代码更规范,所以中大型项目优先选axios。
vue封装axios拦截器怎么处理401状态?
在响应拦截器里判断code == 401,清空本地token,跳转登录页,并顺手销毁当前页面路由,如果是fetch,需要在每个请求后手动写这段逻辑,比较累赘。
vue3请求服务器数据用UseFetch插件还是自己写?
VueUse的useFetch是内置了请求生命周期的一种组合式API封装,适合简单场景,但它的拦截能力不如axios,如果你想统一处理token和错误码,还是得用axios或自己封装fetch。
Vue与服务器的交互不是一个玄学问题,而是一个工程规范问题,把选型搞清楚,拦截器封装到位,跨域和超时都兜住底,你的项目就稳了。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/878836.html


评论列表(4条)
读了这篇文章,我深有感触。作者对封装的理解非常深刻,论述也很有逻辑性。内容既有理论深度,又有实践指导意义,确实是一篇值得细细品味的好文章。希望作者能继续创作更多优秀的作品!
读了这篇文章,我深有感触。作者对封装的理解非常深刻,论述也很有逻辑性。内容既有理论深度,又有实践指导意义,确实是一篇值得细细品味的好文章。希望作者能继续创作更多优秀的作品!
读了这篇文章,我深有感触。作者对封装的理解非常深刻,论述也很有逻辑性。内容既有理论深度,又有实践指导意义,确实是一篇值得细细品味的好文章。希望作者能继续创作更多优秀的作品!
@饼digital429:这篇文章的内容非常有价值,我从中学习到了很多新的知识和观点。作者的写作风格简洁明了,却又不失深度,让人读起来很舒服。特别是封装部分,给了我很多新的思路。感谢分享这么好的内容!