官方文档:Alova.JS - 工作流精简的下一代请求工具 | Alova.JS
“alova” 是一个轻量级的请求策略库,它提供了一套完整的应对复杂请求场景的方案,我们称之为请求策略。通过简单配置参数,可以实现诸如请求共享、分页请求、表单提交、断点续传等复杂请求,而无需编写大量的代码。
Alova是一个独立的请求策略库,用于简化和优化前端的HTTP请求过程,可以与Naive.js等UI框架结合使用
alova 的目标是根据不同的请求场景提供适合的现成请求方案,从而提升应用的可用性、流畅性,降低服务端压力,以及降低开发者的编码量。它并不是完全替代 axios,而是与 axios 等请求库配合使用,提供更高级的功能。
主要特点
-
轻量级:体积小巧,只有 4kb+,是 axios 的 30%。
-
请求策略:提供多种请求策略,如分页请求、表单提交、断点续传等,通过简单配置即可实现复杂请求。
-
状态管理:内置状态管理功能,减少重复代码。
-
缓存支持:支持数据缓存,减少不必要的数据刷新。
-
多框架支持:支持 Vue、React、Svelte 等多种前端框架。
与 axios 的对比
alova 并不是完全替代 axios,而是与 axios 等请求库配合使用,提供更高级的功能。它在请求管理和状态处理上更具优势,尤其是在复杂的请求场景中。
Vue 3 组件,使用了 TypeScript 和 Composition API。主要功能是通过按钮触发一些模拟的 API 请求,用于测试或演示不同的场景,比如登出、刷新令牌、重复请求等。组件中还涉及到国际化(i18n)的使用,以及一些 UI 组件的布局和样式。
1. 安装Alova
在项目中安装Alova库:
npm install alova --save
2. 创建Alova实例
在项目中创建一个Alova实例,用于配置基础路径、适配器等信息:
import { createAlova } from 'alova';
import GlobalFetch from 'alova/GlobalFetch';
import VueHook from 'alova/vue';
export const AlovaInstance = createAlova({
baseURL: '你的域名', // 设置基础请求路径
statesHook: VueHook, // 集成Vue状态管理
requestAdapter: GlobalFetch(), // 使用fetch作为请求适配器
shareRequest: true, // 共享请求
beforeRequest() {}, // 请求前的拦截器
responded: {
onSuccess: async (response: Response) => {
const json = await response.json();
if (json.code === 1) {
return json.data;
} else {
console.log(json.msg);
throw new Error(json.msg);
}
},
onError(error) {
throw new Error(error);
}
}
});
3. 创建请求方法
根据业务需求创建具体的请求方法,例如:
import { AlovaInstance } from './index';
const headers = { 'Content-Type': 'application/json;charset=UTF-8' };
const timeout = 5000;
export const Alova = {
createTodoGet(url: string, params: Record<string, any>) {
return AlovaInstance.Get(url, {
headers,
params,
localCache: {
mode: 'placeholder', // 缓存模式
expire: 60 * 10 * 1000 // 缓存过期时间
},
timeout
});
},
createTodoPost(url: string, data: Record<string, any>, params: Record<string, any>) {
return AlovaInstance.Post(url, data, {
params
});
}
};
4. 在Vue组件中使用
在Vue组件中使用创建好的请求方法,例如:
import { Alova } from '@/alova/api';
// 获取数据
const { data } = useRequest(Alova.createTodoGet('index', { uid: 1399032 }), {
initialData: {} // 初始数据
});
console.log(data);
5. 使用useWatcher自动监听状态变化并发起请求
当某些状态变化时自动发起请求,例如:
import { useWatcher } from 'alova';
const keyword = ref(''); // 搜索关键词
const page = ref(1); // 当前页码
const { data: list } = useWatcher(
() => Alova.createTodoGet('list', { keyword: keyword.value, page: page.value }),
[keyword, page], // 监听的响应式状态
{
immediate: true, // 立即执行
debounce: [500, 0] // 防抖设置
}
);
6. 使用useFetcher预加载数据或跨组件刷新
预加载数据或在跨组件中刷新数据,例如:
import { useFetcher } from 'alova';
const { fetch } = useFetcher();
// 在某个操作成功后预加载下一页数据
onSuccess(() => {
fetch(Alova.createTodoGet('list', { page: page.value + 1 }));
});
通过以上步骤,你可以在项目中使用Alova来处理HTTP请求,利用其提供的各种功能来简化和优化请求过程。
逐行解读
脚本部分(<script setup lang="ts">
)
import { $t } from '@/locales';
import { fetchCustomBackendError } from '@/service-alova/api';
- 导入了两个模块:
-
$t
:用于国际化,从@/locales
路径下导入,通常用于获取不同语言的翻译内容。 -
fetchCustomBackendError
:一个自定义的 API 请求函数,从@/service-alova/api
路径下导入,用于模拟向后端发送请求并处理错误。
-
async function logout() {
await fetchCustomBackendError('8888', $t('request.logoutMsg')); // logout
}
-
定义了一个异步函数
logout
,用于模拟登出操作。 -
调用了
fetchCustomBackendError
函数,传入参数'8888'
(可能是请求的标识符或路径)和$t('request.logoutMsg')
(通过国际化获取登出消息的内容)。 -
注释表明这是登出操作。
async function logoutWithModal() {
await fetchCustomBackendError('7777', $t('request.logoutWithModalMsg')); // logout with modal
}
-
定义了一个异步函数
logoutWithModal
,用于模拟带模态框的登出操作。 -
同样调用了
fetchCustomBackendError
函数,传入参数'7777'
和$t('request.logoutWithModalMsg')
(带模态框的登出消息)。 -
注释表明这是带模态框的登出操作。
async function refreshToken() {
await fetchCustomBackendError('9999', $t('request.tokenExpired')); // refresh token
}
-
定义了一个异步函数
refreshToken
,用于模拟刷新令牌操作。 -
调用了
fetchCustomBackendError
函数,传入参数'9999'
和$t('request.tokenExpired')
(令牌过期的消息)。 -
注释表明这是刷新令牌操作。
async function handleRepeatedMessageError() {
await Promise.all([
fetchCustomBackendError('2222', $t('page.function.request.repeatedErrorMsg1')), // repeated message error
fetchCustomBackendError('2222', $t('page.function.request.repeatedErrorMsg1')), // repeated message error
fetchCustomBackendError('2222', $t('page.function.request.repeatedErrorMsg1')), // repeated message error
fetchCustomBackendError('3333', $t('page.function.request.repeatedErrorMsg2')),
fetchCustomBackendError('3333', $t('page.function.request.repeatedErrorMsg2')),
fetchCustomBackendError('3333', $t('page.function.request.repeatedErrorMsg2'))
]);
}
-
定义了一个异步函数
handleRepeatedMessageError
,用于模拟重复请求消息错误。 -
使用了
Promise.all
并传入一个数组,数组中包含了多个fetchCustomBackendError
的调用。 -
前三个调用传入参数
'2222'
和$t('page.function.request.repeatedErrorMsg1')
,后三个调用传入参数'3333'
和$t('page.function.request.repeatedErrorMsg2')
。 -
注释表明这是重复消息错误操作。
async function handleRepeatedModalError() {
await Promise.all([
fetchCustomBackendError('7777', $t('request.logoutWithModalMsg')), // 模拟重复请求
fetchCustomBackendError('7777', $t('request.logoutWithModalMsg')), // 模拟重复请求
fetchCustomBackendError('7777', $t('request.logoutWithModalMsg'))
]);
}
-
定义了一个异步函数
handleRepeatedModalError
,用于模拟重复请求模态框错误。 -
同样使用了
Promise.all
并传入一个数组,数组中包含了三个fetchCustomBackendError
的调用。 -
每个调用都传入参数
'7777'
和$t('request.logoutWithModalMsg')
。 -
注释表明这是模拟重复请求操作。
模板部分(<template>
)
<NSpace vertical :size="16">
-
使用了
NSpace
组件,设置为垂直布局,间距为 16。
<NCard :title="$t('request.logout')" :bordered="false" size="small" segmented class="card-wrapper">
<NButton @click="logout">{{ $t('common.trigger') }}</NButton>
</NCard>
-
使用了
NCard
组件,标题通过国际化获取'request.logout'
的内容。 -
设置了无边框、小尺寸、分段样式,并添加了
card-wrapper
类。 -
内部包含一个
NButton
按钮,点击时触发logout
函数。 -
按钮文本通过国际化获取
'common.trigger'
的内容。
<NCard :title="$t('request.logoutWithModal')" :bordered="false" size="small" segmented class="card-wrapper">
<NButton @click="logoutWithModal">{{ $t('common.trigger') }}</NButton>
</NCard>
-
类似于上面的
NCard
,标题通过国际化获取'request.logoutWithModal'
的内容。 -
按钮点击时触发
logoutWithModal
函数。
<NCard :title="$t('request.refreshToken')" :bordered="false" size="small" segmented class="card-wrapper">
<NButton @click="refreshToken">{{ $t('common.trigger') }}</NButton>
</NCard>
-
类似于上面的
NCard
,标题通过国际化获取'request.refreshToken'
的内容。 -
按钮点击时触发
refreshToken
函数。
<NCard
:title="$t('page.function.request.repeatedErrorOccurOnce')"
:bordered="false"
size="small"
segmented
class="card-wrapper"
>
<NButton @click="handleRepeatedMessageError">{{ $t('page.function.request.repeatedError') }}(Message)</NButton>
<NButton class="ml-12px" @click="handleRepeatedModalError">
{{ $t('page.function.request.repeatedError') }}(Modal)
</NButton>
</NCard>
-
使用了
NCard
组件,标题通过国际化获取'page.function.request.repeatedErrorOccurOnce'
的内容。 - 内部包含两个
NButton
按钮:-
第一个按钮点击时触发
handleRepeatedMessageError
函数,文本通过国际化获取'page.function.request.repeatedError'
的内容,并添加了(Message)
。 -
第二个按钮点击时触发
handleRepeatedModalError
函数,文本同样通过国际化获取,并添加了(Modal)
。还添加了ml-12px
类,用于设置左边距。
-
样式部分(<style scoped>
)
<style scoped></style>
-
定义了一个空的样式部分,
scoped
表示这些样式只在当前组件中生效。目前没有具体的样式规则。
总结
该组件通过多个按钮触发不同的模拟 API 请求操作,主要用于测试或演示不同的场景,如登出、带模态框的登出、刷新令牌、重复请求等。组件使用了 Vue 3 的 Composition API 和 TypeScript,结合了国际化和 UI 组件库,结构清晰,功能明确。