经过几个月的精心打磨,很高兴向大家宣布 alova 3.3.0 正式发布!
在过去半年时间里,我们也深入听取了社区开发者的反馈,针对实际开发中的痛点,在业务逻辑方面加强了不少。从 SSR 支持到 AI 应用,服务端场景下的业务逻辑,从分布式缓存到文件上传等等。
什么是alova
alova是一个请求工具集,帮助开发者极致高效地集成你的APIs,它完美兼容你最喜欢的HTTP client和UI框架,快速开发客户端和服务的应用的业务逻辑,同时让API信息与代码进行交互,像虫洞一样拉近后端协作距离。
如果觉得alova还不错,真诚希望你可以尝试体验一下,也可以给我们来一个免费的github stars。
访问alovajs的官网查看更多详细信息:alovajs官网。
更新亮点预览
功能增强
- nuxt3 优化:完美适配 Nuxt3,支持客户端和服务端的状态同步,以及await useRequest 语法
- usePagination 重构:告别繁琐的额外请求,一键实现增删改操作
- useSSE 升级:支持 POST 请求和自定义 headers
全新策略
- 验证码策略:分布式验证码发送和验证解决方案
- 上传策略:万能文件上传,支持多种数据格式
核心特性
- alova.Request:更好的 TypeScript 类型支持
- baseURL优化:带协议 URL 自动忽略 baseURL 拼接
- querystring 支持:params 参数支持字符串格式
存储适配器
- Redis 适配器:分布式集群存储场景
- File 适配器:单机多进程原子化场景
接下来具体了解下吧。
一、useHook 功能增强
完美适配 Nuxt3
alova 3.3.0 借鉴了 Nuxt3 的优秀设计,实现了比useFetch
更好的体验,在使用useRequest、useWatcher等几乎所有的hooks时不仅可以同步两端的数据,避免在客户端重复请求,还可以在服务端和客户端同步例如Date
,Error
等以及自定义类型的数据。
Nuxt3 的写法:
javascript
<script setup>
const { data: count } = await useFetch('/api/count');
</script>
现在 alova 中可以这样写:
javascript
<script setup>
const { data, loading } = await useRequest(...);
</script>
在实际中表现如下:
- 在服务端会进行一次真实的请求
- 在客户端不会重复请求
- data、loading 等状态在客户端依然可以正常使用
这需要配合本次新增的nuxtHook:
javascript
import { createAlova } from 'alova';
import nuxtHook from 'alova/nuxt';
export const alovaInstance = createAlova({
// ...
statesHook: nuxtHook({
nuxtApp: useNuxtApp // 必须指定useNuxtApp
})
});
usePagination 优化
在之前的版本中,如果要对列表项进行增删改操作,需要先定义额外的 useRequest,然后再调用 usePagination 的操作函数,代码显得相当繁琐:
3.2.x 的写法中,操作列表数据需要额外定义useRequest
javascript
const { data, loading, page, pageSize, remove } = usePagination(getList);
const { send: removeItem, loading: removing } = useRequest(id => removeItem(id), {
immediate: false
}).onSuccess(({ args: [id] }) => {
remove(id);
});
const handleRemove = id => {
removeItem(id);
};
3.3.0 中定义actions即可:
javascript
// 简洁的新写法
const {
...
remove,
removing
} = usePagination(getList, {
actions: {
remove: id => removeItem(id),
replace: item => replaceItem(item)
}
});
const handleRemove = id => {
remove(id); // 直接调用即可,内部会自动触发请求
};
新增的状态管理让UI控制更精确,以下是一个vue3的示例:
html
<template>
<table>
<tr v-for="(item, index) in list" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>
<button
:loading="removing.includes(index)"
@click="remove(item.id)"
>
删除
</button>
</td>
</tr>
</table>
</template>
<script setup>
const { data: list, remove, removing } = usePagination(getList, {
actions: {
remove: id => removeUser(id)
}
});
</script>
usePagination优化小结:
- actions 配置项:可配置 insert、remove、replace 对应的请求函数
- status 状态:包含空字符串(正常)、loading(加载中)、removing(删除中)、inserting(插入中)、replacing(替换中)
- 精确的行级状态:removing 是数组,replacing 是数字,可以精确控制每一行的状态
useSSE 优化
随着AI应用的兴起,Server-Sent Events (SSE) 变得越来越重要。我们团队深入研究了 AI 应用的实际需求,对 useSSE 进行了重大升级:
核心改进:
- 使用 fetch 替代 EventSource:支持 POST 请求、数据传输和 headers 传递
- 新增 responseType 参数:自动转换为 JSON 数据
实际使用示例:
javascript
// 支持 POST 请求和自定义 headers
const streamMethod = () => alova.Post('/api/chat-stream', {
prompt: '请告诉我关于人工智能的发展历史',
temperature: 0.7
}, {
headers: {
'Authorization': 'Bearer your-token',
'Content-Type': 'application/json'
},
})
const { data, readyState, onMessage, onError } = useSSE(, {
responseType: 'json', // 自动转换为 JSON
immediate: true
});
// 监听流式数据
onMessage(event => {
console.log('收到AI回复:', event.data);
});
// 处理错误
onError(error => {
console.error('连接错误:', error);
});
二、全新请求策略
服务端验证码策略:分布式验证码解决方案
对于需要验证码功能的应用,alova 3.3.0 提供了完整的服务端验证码解决方案:
javascript
const { validateCaptcha, sendCaptcha } = createCaptchaProvider({
// 可再次发送验证码的间隔时间
resetTime: 60 * 1000,
// 验证码过期时间
expireTime: 60 * 1000 * 5,
// 命名空间,防止命名冲突
keyPrefix: 'alova-captcha',
// 验证码存储适配器,使用redis适配器实现分布式验证码处理
store: redisAdapter,
// 重发时是否使用存储中的验证码
resendFormStore: true,
// 验证码生成规则
codeSet: {
chars: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
length: 4
}
});
// 发送验证码
await sendCaptcha((code, key) => alova.Post('/api/captcha', {
code,
mobile: key
}), {
key: mobile
});
// 验证验证码
const isValid = await verifyCaptcha(submitedCaptcha, mobile);
这个策略特别适合分布式环境,支持多种存储适配器,并且提供了完善的过期和重发机制。
客户端上传策略:万能的文件上传
新的上传策略支持多种数据格式直接上传,支持获得总上传进度和单个文件的上传进度,还支持批量上传:
- base64 字符串
- File 对象
- Blob 对象
- ArrayBuffer 对象
- Canvas 对象
javascript
// 支持各种格式的上传
const { upload, uploading, progress, appendFiles } = useUploader(uploadAPI);
// 添加文件
await appendFiles({ file: fileObject });
// 添加canvas图片
await appendFiles({ file: canvasElement });
// 添加base64
await appendFiles({ file: base64String });
// 触发上传
await upload();
这个策略解决了三个常见场景:
- 上传组件样式不符合需求时的自定义上传
- 无法使用上传组件时的编程式上传(如Canvas图片)
- 多种数据格式混合上传的场景
三、核心特性增强
新增 alova.Request:更好的类型支持
之前使用 new Method
时,响应数据类型不好指定。新的 alova.Request
提供了类似 axios 的使用体验:
javascript
// 直接指定响应类型
interface User {
id: number;
name: string;
age: number;
}
const method = alova.Request<User>({
url: '/xxx',
method: 'post',
data: { name: 'John' },
headers: { 'Content-Type': 'application/json' }
});
const response = await method;
// response 现在有完整的 User 类型支持
// 或者通过 transform 指定类型
const method2 = alova.Request({
url: '/xxx',
method: 'post',
data: { name: 'John' },
transform(data: User) {
return { ...data, fullName: `${data.name}(${data.age})` };
}
});
baseURL 自动忽略机制
当请求URL包含协议时,会自动忽略 baseURL 的拼接:
javascript
const alova = createAlova({
baseURL: 'http://localhost:3000',
// ...
});
// 这个请求会直接访问指定URL,不会拼接baseURL
alova.Get('http://localhost:8080/data');
这个特性在处理跨域请求或多个API服务时特别有用。
params 支持 querystring 格式
现在可以直接传入 querystring 格式的参数:
javascript
// 直接传入querystring
const method = alova.Get('/xxx', {
params: 'a=1&b=2&c[]=3&c[]=4'
});
// 全局处理复杂参数
import qs from 'qs';
createAlova({
beforeRequest(method) {
method.config.params = qs.stringify(method.config.params, {
arrayFormat: "brackets"
});
}
});
四、新增存储适配器
Redis 存储适配器:分布式缓存
为了支持服务端分布式集群下的缓存共享,新增了 Redis 存储适配器:
javascript
import { RedisStorageAdapter } from '@alova/storage-redis';
const alovaInstance = createAlova({
// ...
l2Cache: new RedisStorageAdapter({
host: 'localhost',
port: 6379,
// 其他Redis配置...
})
});
内部使用 ioredis 实现,提供了完整的 Redis 功能支持,在请求速率限制、验证码发送场景都可以直接使用。
File 存储适配器:单机集群缓存
对于单机多进程的场景,提供了文件存储适配器:
javascript
import { FileStorageAdapter } from '@alova/storage-file';
const alovaInstance = createAlova({
// ...
l2Cache: new FileStorageAdapter({
directory: './cache'
})
});
通过 rename + queue 实现多进程的原子化操作,确保数据一致性。
最后
此时我还想说的是,无论你是在开发传统的 Web 应用,还是在构建现代的 AI 应用,alova 3.3.0 都能给你提供强大而优雅的解决方案。
如果觉得alova还不错,真诚希望你可以尝试体验一下,也可以给我们来一个免费的github stars。
访问alovajs的官网查看更多详细信息:alovajs官网。
有兴趣可以加入我们的交流社区,在第一时间获取到最新进展,也能直接和开发团队交流,提出你的想法和建议。
有任何问题,你可以加入以下群聊咨询,也可以在github 仓库中发布 Discussions,如果遇到问题,也请在github 的 issues中提交,我们会在最快的时间解决。