写在前面:你可能每天都在重复这些工作
javascript
// 场景 1:基础请求
const [loading, setLoading] = useState(false);
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
setLoading(true);
fetch('/api/users')
.then(res => res.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(err => {
setError(err);
setLoading(false);
});
}, []);
// 场景 2:带重试的请求(你已经写了 50 行,还在考虑要不要加重试)
// 场景 3:分页加载(数据要拼接、缓存要管理、预加载要考虑...)
// 场景 4:表单提交(验证、持久化、提交后重置...)
如果你觉得这些场景似曾相识,那么这篇文章可能改变你对前端请求的认知。
alova 是什么?不是什么
❌ 不是简单的 axios/fetch 封装
很多人第一反应:"这不就是封装了 axios 吗?"
错。
alova 采用的是适配器模式 ,你可以选择任何底层请求库:axios、fetch、XHR、SuperAgent,甚至 Taro/UniApp 的跨平台适配器。它只是把不同库的接口转换成统一规范,核心是请求策略编排。
✅ 是一个请求策略引擎
alova 的野心更大:它要解决所有请求相关的痛点,让你像搭积木一样组合各种高级特性,用最少的代码实现最复杂的功能。
20+ 高级特性全景图
🎯 核心请求策略(3大基石)
1. useRequest - 请求状态自动化
javascript
// 传统写法:你需要手动管理 loading、data、error
// alova 写法:一行搞定
const { loading, data, error, send } = useRequest(getUserList);
魔法在哪里?
- 自动管理 loading 状态
- 自动响应式更新数据
- 自动错误处理
- 支持事件订阅(onSuccess、onError、onComplete)
2. useWatcher - 智能响应请求
javascript
// 搜索框防抖请求,传统写法:useEffect + 定时器
// alova 写法:
const { data } = useWatcher(
(keyword) => searchApi(keyword),
[keyword], // 监听 keyword 变化
{ debounce: 300 } // 内置防抖
);
3. useFetcher - 无组件数据获取
javascript
// 预加载数据,但不更新当前组件状态
const { fetch } = useFetcher();
useEffect(() => {
// 鼠标悬停时预加载详情页数据
fetch(getDetailApi(id));
}, []);
🚀 高级业务 Hooks(解决 80% 的复杂场景)
场景 1:分页列表(你写过 500 行,它用 5 行)
javascript
const {
data,
page,
pageCount,
isLastPage,
insert, // 插入列表项
remove, // 删除列表项
replace, // 替换列表项
refresh // 刷新指定页
} = usePagination(
(page, pageSize) => getUserList({ page, pageSize }),
{
initialPage: 1,
initialPageSize: 20,
preloadPreviousPage: true, // 自动预加载上一页
preloadNextPage: true // 自动预加载下一页
}
);
// 删除用户,自动更新列表、总数、预加载缓存
remove(userId);
它帮你做了什么:
- ✅ 自动拼接数据(下拉加载/翻页模式切换)
- ✅ 自动预加载上一页/下一页
- ✅ 智能缓存管理(删除某项,自动调整下一页缓存)
- ✅ 虚拟列表优化(只请求需要的数据)
- ✅ 跨页面状态同步
场景 2:表单管理(持久化、验证、提交流程)
javascript
const {
form,
updateForm,
reset,
send
} = useForm(
(formData) => submitForm(formData),
{
initialForm: { username: '', email: '' },
store: true, // 自动持久化到本地存储
resetAfterSubmiting: true, // 提交后自动重置
immediate: false
}
);
// 用户刷新页面,表单数据自动恢复
// 提交后自动重置,无需手动调用 reset()
场景 3:智能重试(指数退避、条件重试)
javascript
const { send, stop, onRetry, onFail } = useRetriableRequest(
unstableApi,
{
retry: 3, // 最多重试 3 次
backoff: { // 指数退避策略
delay: 1000,
multiplier: 2
}
}
);
// 重试时触发
onRetry(event => {
console.log(`第 ${event.retryTimes} 次重试,延迟 ${event.delay}ms`);
});
// 最终失败时触发
onFail(event => {
console.error('重试失败,原因:', event.error);
});
// 手动停止重试
stop();
场景 4:静默队列请求(断网重发)
javascript
const { send } = useSQRequest(
(data) => reportAnalytics(data),
{
maxQueue: 100, // 最多缓存 100 个请求
queueWhenDisconnected: true // 断网时入队
}
);
// 即使网络断开,请求也会缓存到队列中
// 网络恢复后自动按顺序发送
场景 5:串行请求(确保执行顺序)
javascript
const { send } = useSerialRequest(
(taskId) => {
return getTaskStatus(taskId);
},
{
// 确保每次只有一个请求在执行
// 新请求会排队等待
}
);
场景 6:实时推送(Server-Sent Events)
javascript
const {
data,
send,
onMessage,
onClose
} = useSSE(
() => new EventSource('/api/events'),
{
intercept: true, // 拦截消息,自定义处理
reconnect: true // 断线自动重连
}
);
onMessage((event) => {
console.log('实时消息:', event.data);
});
🛠️ 底层高级能力(隐形超级英雄)
1. 请求共享(避免重复请求)
javascript
// 组件 A
const { data: data1 } = useRequest(getUserList);
// 组件 B(同时渲染)
const { data: data2 } = useRequest(getUserList);
// 只会发送一个请求,两个组件共享响应
原理: 通过请求指纹识别,同一时间相同请求只发一次,后续请求等待或复用结果。
2. 多级缓存系统
javascript
createAlova({
cacheFor: {
getUserList: { mode: 'memory', expire: 60000 },
getDetail: { mode: 'storage', expire: 3600000 }
}
});
缓存模式:
- MEMORY:内存缓存,适合临时数据
- STORAGE:本地存储,适合持久化
- STORAGE_RESTORE:刷新页面后恢复
3. Token 自动认证
javascript
import { createTokenAuthentication } from 'alova/client';
createAlova({
// ... 配置
beforeRequest(method) {
// 自动注入 Token
tokenAuth.addTokenToHeader(method);
}
});
const tokenAuth = createTokenAuthentication({
login: (username, password) => loginApi(username, password),
logout: () => logoutApi(),
assignToken: (response) => response.token,
tokenRefresher: (refreshToken) => refreshApi(refreshToken)
});
自动处理:
- Token 过期自动刷新
- 多个请求同时过期只刷新一次
- 刷新失败自动重试登录
4. 中间件系统
javascript
useRequest(getUserList, {
middleware: (context, next) => {
// 请求前
console.log('开始请求');
return next().then(response => {
// 响应后
console.log('请求完成');
return response;
});
}
});
5. OpenAPI 自动生成接口
bash
# 一键生成类型安全的接口代码
npx alova-codegen --url http://api.example.com/openapi.json
生成结果:
- 完整的 TypeScript 类型定义
- 自动化的接口调用方法
- 请求/响应类型推导
6. 跨标签页状态共享
javascript
// 标签页 A
const { data } = useRequest(getUserList);
// 标签页 B(用户在 A 中刷新数据)
// B 中自动同步最新数据,无需手动刷新
📊 对比:传统方案 vs alova
| 场景 | axios + React Query | alova | 减少代码量 |
|---|---|---|---|
| 基础请求 | 30 行 | 3 行 | 90% |
| 分页列表 | 200 行 | 20 行 | 90% |
| 表单管理 | 150 行 | 15 行 | 90% |
| 智能重试 | 100 行 | 10 行 | 90% |
| Token 认证 | 80 行 | 15 行 | 81% |
| 总计 | 560 行 | 63 行 | 89% |
💡 为什么选择 alova?
1. 开箱即用的高级特性
其他库需要你自己写中间件、插件,alova 已经帮你写好了。
2. 真正的跨框架
React/Vue/Svelte/Solid/Nuxt 同一套 API,技能复用率 100%。
3. 类型安全优先
从请求参数到响应数据,完整的 TypeScript 类型推导。
4. 性能极致优化
请求共享、多级缓存、智能预加载,这些都是内置的。
5. 开发效率提升 10 倍
从 560 行代码到 63 行代码,这就是差距。
🎬 快速上手
bash
npm install alova @alova/client
javascript
import { createAlova } from 'alova';
import { useRequest } from '@alova/client';
import adapterFetch from 'alova/fetch';
const alova = createAlova({
baseURL: 'https://api.example.com',
requestAdapter: adapterFetch()
});
// 只需要这样
const { data, loading } = useRequest(alova.Get('/users'));
结语
前端开发不应该把时间浪费在重复的请求管理上。
alova 的 20+ 高级特性,本质上是对前端请求场景的深度抽象。它不是要替代 axios 或 fetch,而是要解决这些库无法解决的业务痛点。
你的时间应该花在产品逻辑上,而不是请求的加载、缓存、重试、错误处理这些重复工作中。
准备好了吗?从"请求地狱"到"请求天堂",只差一个 alova。