一行代码搞定Vue3异步请求:vue3-request让状态管理从地狱到天堂
用了3年Vue3+TS,终于找到了异步请求管理的完美解决方案!再也不用写那些重复的loading、error代码了...
😫 程序员的日常崩溃现场
作为一个Vue3+TypeScript的深度用户,我相信你一定写过这样的代码:
ts
<script setup lang="ts">
import { axios } from 'axios'
// 每个接口都要写这一套,真的很烦... 😤
const loading = ref<boolean>(false)
const error = ref<Error | null>(null)
const data = ref<UserInfo | null>(null)
interface UserInfo {
id: number
name: string
email: string
}
const controller = new AbortController()
const getUserInfo = async () => {
loading.value = true
error.value = null
try {
const res = await axios.get('/api/userInfo', {
signal: controller.signal
})
data.value = res
} catch (err) {
error.value = err
} finally {
loading.value = false
}
}
onMounted(() => {
getUserInfo()
})
onUnmounted(() => {
controller.abort() // 还得记得清理,漏了就内存泄漏
})
</script>
每次写这种代码我都想吐槽:
- 🤮 样板代码太多:每个请求都要重复这些状态管理
- 😵 类型定义繁琐:loading、error、data 都要手动定义类型
- 🐛 容易出bug:忘记清理AbortController,忘记处理error
- 🔄 重复劳动:复制粘贴改改改,程序员的尊严何在?
停止这种痛苦吧! 让我们看看 vue3-request 如何用一行代码解决所有问题。
✨ vue3-request:异步请求的终极解决方案
🎯 核心亮点
- 🚀 一行代码搞定:loading、error、data 状态自动管理
- 💎 完美 TypeScript:全类型推导,告别 any
- ⚡ 智能请求中止:自动生成 AbortSignal,避免内存泄漏
- 💾 内置缓存 & SWR:极致性能优化
- 🔄 错误重试:网络异常自动重试
- 🎭 插件化架构:满足复杂业务场景
🚀 5秒上手:看看威力有多大
安装
bash
# 我推荐用 pnpm,速度快
pnpm add vue3-request
# 当然 npm/yarn 也行
npm install vue3-request
yarn add vue3-request
基础使用:从 50 行代码到 1 行代码
ts
<script setup lang="ts">
import { axios } from 'axios'
import { useRequest } from 'vue3-request'
interface UserInfo {
id: number
name: string
email: string
}
const getUserInfo = async (): Promise<UserInfo> => {
return await axios.get('/api/user', {
signal: signal.value // 🔥 自动注入 AbortSignal
})
}
// ✨ 一行代码解决所有状态管理!
const {
data, // Ref<UserInfo | undefined> 完美类型推导
loading, // Ref<boolean>
error, // Ref<Error | undefined>
signal, // Ref<AbortSignal> 自动生成
refresh, // () => void
abort // () => void
} = useRequest(getUserInfo)
</script>
对比效果:
- ❌ 传统方式:50+ 行代码,手动状态管理
- ✅ vue3-request:1 行代码,自动搞定一切
✨ 手动触发 + TypeScript 参数类型检查
typescript
interface SearchParams {
keyword: string
page: number
}
const searchUsers = async (params: SearchParams): Promise<User[]> => {
return await api.search(params)
}
const { run, runAsync, data, loading } = useRequest(searchUsers, {
manual: true // 手动触发
})
// TypeScript 会检查参数类型,传错了立马报错
run({ keyword: 'vue', page: 1 }) // ✅ 正确
run({ name: 'vue' }) // ❌ TypeScript 报错,参数类型不匹配
// 异步调用也有完整的类型支持
const handleSearch = async () => {
try {
const result = await runAsync({ keyword: 'react', page: 1 })
// result 的类型是 User[],智能提示完美
console.log(result[0].name)
} catch (error) {
console.error('搜索失败:', error)
}
}
💾 缓存 + SWR,性能优化神器
typescript
interface ApiResponse<T> {
code: number
data: T
message: string
}
const getUserList = async (): Promise<ApiResponse<User[]>> => {
// 模拟真实项目的接口调用
return axios.get<ApiResponse<User[]>>('/api/users')
}
const { data, loading } = useRequest(getUserList, {
cacheKey: 'user-list', // 缓存key
staleTime: 8000, // 8秒内不重复请求
cacheTime: 10 * 60 * 1000, // 10分钟后清除缓存
})
// 用户体验:
// 1. 首次访问:显示loading,获取数据
// 2. 组件重新加载:立即显示缓存数据,后台静默更新
// 3. 多个组件共享同一个缓存,请求只会发一次!
🛡️ 请求中止,妈妈再也不用担心内存泄漏
typescript
const searchAPI = async (keyword: string): Promise<SearchResult[]> => {
// signal 自动提供,不用手动创建 AbortController
const response = await fetch(`/api/search?q=${keyword}`, {
signal: signal.value
})
return response.json()
}
// abort方法可手动直接调用中止请求
const { signal, abort, run } = useRequest(searchAPI, { manual: true })
// 搜索框输入,自动取消上一次请求
const handleSearch = (keyword: string) => {
run(keyword) //前置请求中止: 内部自动调用abort方法中止前一次未完成的请求,发起新请求
}
// 组件销毁时自动 abort,无需手动处理
🔁 轮询监控
typescript
interface SystemStatus {
cpu: number
memory: number
disk: number
timestamp: number
}
const getSystemStatus = async (): Promise<SystemStatus> => {
const response = await fetch('/api/system/status')
return response.json()
}
const { data: systemStatus, error } = useRequest(getSystemStatus, {
pollingInterval: 5000, // 5秒轮询一次
pollingWhenHidden: false, // 页面隐藏时停止轮询
refreshOnWindowFocus: true, // 窗口聚焦时刷新
})
🧩 插件系统
ts
<script setup lang="ts">
import { useRequest, definePlugin } from 'vue3-request'
// 🎯 自定义日志插件
const logPlugin = definePlugin<UserInfo, [], { logLevel: string }>(
(requestInstance, options) => ({
onBefore: () => {
console.log(`[${options.logLevel}] 🚀 请求开始`)
},
onSuccess: (data) => {
console.log(`[${options.logLevel}] ✅ 请求成功:`, data)
},
onError: (error) => {
console.error(`[${options.logLevel}] ❌ 请求失败:`, error.message)
}
})
)
// 🎯 消息提示插件
const messagePlugin = definePlugin<UserInfo, []>(
(requestInstance) => ({
onSuccess: () => {
// 假设使用 Element Plus
ElMessage.success('数据加载成功')
},
onError: (error) => {
ElMessage.error(`加载失败: ${error.message}`)
}
})
)
// 🚀 使用多个插件
const { data, loading, error } = useRequest(
fetchUser,
{
logLevel: 'info', // 插件配置,完美的类型提示
refreshOnWindowFocus: true
},
[logPlugin, messagePlugin] // 插件组合
)
</script>
高级用法(生产环境推荐)
typescript
// hooks/useUserList.ts - 抽取成自定义Hook
import { useRequest } from 'vue3-request'
import type { Ref } from 'vue'
interface UserListOptions {
autoRefresh?: boolean
cacheEnabled?: boolean
}
export function useUserList(options: UserListOptions = {}) {
const { autoRefresh = true, cacheEnabled = true } = options
return useRequest(fetchUsers, {
// 缓存配置
...(cacheEnabled && {
cacheKey: 'user-list',
staleTime: 5 * 60 * 1000, // 保鲜5分钟
cacheTime: 10 * 60 * 1000, // 缓存10分钟
}),
// 自动刷新
...(autoRefresh && {
pollingInterval: 30 * 1000, // 30秒轮询一次
refreshOnWindowFocus: true, // 窗口聚焦刷新
}),
// 错误重试
retryCount: 3,
retryInterval: 1000,
// 生命周期钩子
onSuccess: (data) => {
console.log('用户列表加载成功:', data.length)
},
onError: (error) => {
console.error('用户列表加载失败:', error)
// 这里可以接入错误监控
}
})
}
📊 性能对比:数据说话
功能特性 | 传统方式 | vue3-request |
---|---|---|
代码量 | 50+ 行 | 1 行 |
类型安全 | 手动维护 | 自动推导 |
请求中止 | 复杂实现 | 自动管理 |
缓存策略 | 需要造轮子 | 内置 SWR |
错误重试 | 手写逻辑 | 配置即用 |
防抖节流 | 额外依赖 | 内置支持 |
轮询功能 | 复杂实现 | 一行配置 |
为什么选择 vue3-request?
🚀 开发效率飞升
typescript
// 对比:实现一个带缓存、重试、防抖的搜索功能
// ❌ 传统方式:100+ 行代码
// ✅ vue3-request:5 行代码
const { data, loading, run } = useRequest(searchApi, {
manual: true,
debounceWait: 300,
cacheKey: 'search',
errorRetryCount: 3
})
💭 总结:为什么你应该试试 vue3-request?
说实话,用了 vue3-request 之后,我再也回不去手写那些状态管理了。它让我的代码:
- 更干净 📝:告别样板代码,专注业务逻辑
- 更安全 🛡️:TypeScript 类型安全 + 自动请求清理
- 更高效 ⚡:内置缓存、防抖、重试等优化策略
- 更可靠 🔒:经过实际项目验证的最佳实践
如果你也在用 Vue3 + TypeScript 开发项目,强烈建议试试 vue3-request。它不是银弹,但绝对能让你的开发体验提升一个档次!
相关链接:
GitHub地址 github.com/Flame-00/vu... 点个Star吧!