一、为什么选择VueUse的useFetch?
在Vue3生态中,HTTP请求处理一直是开发者关注的重点。传统方案如axios
需要手动管理请求状态,而VueUse提供的useFetch
通过组合式API实现了开箱即用的响应式请求管理。对比发现:
- 代码量减少:自动处理
loading
、error
状态 - 响应式集成:数据变更自动触发视图更新
- TS友好:完整的TypeScript类型推断
- 超时重试:内置请求重试机制
- 体积轻盈:仅需引入@vueuse/core(约4KB)
二、快速搭建基础项目环境(技术栈明确声明)
本文使用以下技术栈组合:
- Vue3:组合式API基础框架
- Vite4:构建工具
- @vueuse/core 9.0:工具库
- TypeScript5:语言支持
# 使用以下命令创建初始项目
npm create vite@latest vueuse-fetch-demo -- --template vue-ts
cd vueuse-fetch-demo
npm install @vueuse/core
三、useFetch基础用法示例
1. GET请求基础实现
<script setup lang="ts">
import { useFetch } from '@vueuse/core'
// 基础GET请求(含智能类型推断)
const { data, isFetching, error } = useFetch('https://api.example.com/posts/1')
</script>
<template>
<!-- 响应式展示层 -->
<div v-if="isFetching">加载动画...</div>
<div v-else-if="error">错误:{{ error.message }}</div>
<div v-else>{{ data }}</div>
</template>
2. POST请求配合拦截器
// utils/request.ts
export const useCustomFetch = (url: string, options?: any) => {
return useFetch(url, {
// 统一请求配置
timeout: 10000,
retry: 3,
// 请求拦截
beforeFetch({ options }) {
options.headers = {
...options.headers,
Authorization: `Bearer ${localStorage.getItem('token')}`
}
return { options }
},
// 响应拦截
afterFetch(ctx) {
if (ctx.data.code !== 200) {
throw new Error(ctx.data.message)
}
ctx.data = ctx.data.result
return ctx
}
}).json() // 自动解析JSON
}
// 组件内使用
const { execute } = useCustomFetch('https://api.example.com/login', {
method: 'POST',
body: JSON.stringify({ username: 'admin', password: '123456' })
})
四、高级功能实战演示
1. 请求取消与竞态处理
const { abort, execute } = useFetch('https://api.example.com/search')
// 用户触发搜索
const handleSearch = async (keyword: string) => {
// 终止进行中的请求
if (abort) abort()
// 发起新请求
await execute({
query: { q: keyword }
}).then(({ data }) => {
console.log('最新结果:', data)
})
}
2. 自动重试与超时策略
// 配置重试策略
const { data } = useFetch('https://api.example.com/status', {
retry: 5, // 最大重试次数
retryDelay: 1000, // 重试间隔
timeout: 3000, // 单次请求超时
onFetchError(ctx) {
console.log('最终请求失败:', ctx.error)
}
})
3. 实时数据轮询
import { useIntervalFn } from '@vueuse/core'
const { data, execute } = useFetch('https://api.example.com/stock')
// 每10秒刷新数据
const { pause, resume } = useIntervalFn(() => {
execute()
}, 10000)
// 页面隐藏时暂停轮询
const { stop } = usePageVisibility({
onChange: (visible) => {
visible ? resume() : pause()
}
})
五、企业级应用场景剖析
1. 高频数据展示看板
// dashboard.vue
const { data: salesData } = useFetch('/api/sales', {
refetch: true, // 窗口聚焦时自动刷新
initialData: [] // 防止页面抖动
})
2. 表单提交防抖优化
const { execute } = useFetch('/api/submit', {
immediate: false
})
// 带500ms防抖的提交
const handleSubmit = useDebounceFn(async () => {
await execute({
method: 'POST',
body: formData.value
})
}, 500)
六、技术方案对比分析
优势亮点:
- 响应式状态集成:自动同步
loading/error/data
到视图 - 配置继承性:通过拦截器实现全局配置
- 体积效益:无需额外安装HTTP库
- 组合式扩展:轻松配合
useDebounceFn
等工具
已知局限性:
- 多请求管理:缺乏类似
axios.all
的批处理方案 - 上传进度:不支持文件上传进度监听
- 缓存策略:需自行实现缓存逻辑
七、关键注意事项
1. 服务端渲染(SSR)适配
// 仅在客户端执行请求
const { data } = useFetch('https://api.example.com', {
server: false // 禁用SSR
})
2. TypeScript类型强化
interface UserProfile {
id: number
name: string
avatar: string
}
// 明确响应类型
const { data } = useFetch<UserProfile>('https://api.example.com/me')
.json()
3. 性能优化策略
// 大文件下载使用分块处理
const { data } = useFetch('/api/large-file', {
refetch: false, // 禁止重复请求
timeout: 0 // 取消超时限制
})
八、完整技术方案总结
经过深度实践验证,useFetch
在以下场景表现卓越:
- 需要快速实现CRUD操作的内部系统
- 对包体积敏感的低代码平台
- 需要高频更新数据的可视化项目
- 重视开发体验的初创团队
推荐配合策略:
- 结合
useStorage
做本地缓存 - 使用
useFetch
处理基础请求 - 复杂场景配合
axios
扩展