构建Client-Server交互层
提示
这是一个深入使用 alova 总结的实践经验,阅读前请确保已经掌握了alova 基础部分的内容,你也可以观看5 分钟快速入门视频。
你可以组合 alova 的各种特性实现应用的 Client-Server 交互层(CS 交互层),CS 交互层将会管理你的响应数据和 useHooks 所创建的响应式状态,它们将会在 CS 交互层中通过 method 实例建立映射关系,从而消除组件层级的限制,你可以在任意的 UI 组件中通过 method 实例来访问、修改和刷新 CS 交互层的数据,以及调用 useHooks 的 actions。
让我们来看看 CS 交互层可以带来哪些好处。
请求点分离
在传统做法中,当一个页面被切分成了多个组件时,我们需要从根节点请求数据并分发到子组件中,这样无疑提高了数据传递的复杂度。
现在,你可以在不同组件中发起相同的请求,CS 交互层中将会合并请求,并将数据分发到这些组件中。
让我们来具体看看示例代码。
- vue
- react
- svelte
- PageRoot.vue
- ./component/profile.vue
- ./component/assets.vue
<template>
<profile></profile>
<assets></assets>
</template>
<script setup>
import Profile from './component/profile.vue';
import Assets from './component/assets.vue';
</script>
<template>
<div v-if="loading">loading...</div>
<div v-else>
<p>name: {{ data.name }}</p>
<p>age: {{ data.age }}</p>
</div>
</template>
<script setup>
import { useRequest } from 'alova/client';
const { loading, data } = useRequest(alova.Get('/api/user'));
</script>
<template>
<div>
<div v-if="loading">loading...</div>
<div v-else>
<p>balance: {{ data.balance }}</p>
<p>coins: {{ data.coins }}</p>
</div>
</div>
</template>
<script setup>
import { useRequest } from 'alova/client';
const { loading, data } = useRequest(alova.Get('/api/user'));
</script>
- PageRoot.jsx
- ./component/profile.jsx
- ./component/assets.jsx
import Profile from './component/profile';
import Assets from './component/assets';
const App = () => {
return (
<>
<profile></profile>
<assets></assets>
</>
);
};
import { useRequest } from 'alova/client';
const Profile = () => {
const { loading, data } = useRequest(alova.Get('/api/user'));
return loading ? (
<div>loading...</div>
) : (
<div>
<p>name: {data.name}</p>
<p>age: {data.age}</p>
</div>
);
};
import { useRequest } from 'alova/client';
const Assets = () => {
const { loading, data } = useRequest(alova.Get('/api/user'));
return loading ? (
<div>loading...</div>
) : (
<div>
<p>balance: {data.balance}</p>
<p>coins: {data.coins}</p>
</div>
);
};
- PageRoot.svelte
- ./component/profile.svelte
- ./component/assets.svelte
<script>
import Profile from './component/profile.svelte';
import Assets from './component/assets.svelte';
</script>
<profile></profile>
<assets></assets>
<script>
import { useRequest } from 'alova/client';
const { loading, data } = useRequest(alova.Get('/api/user'));
</script>
{#if $loading}
<div>loading...</div>
{#else}
<div>
<p>name: {$data.name}</p>
<p>age: {$data.age}</p>
</div>
{/if}
<script>
import { useRequest } from 'alova/client';
const { loading, data } = useRequest(alova.Get('/api/user'));
</script>
{#if $loading}
<div>loading...</div>
{#else}
<div>
<p>balance: {$data.balance}</p>
<p>coins: {$data.coins}</p>
</div>
{/if}
响应式状态集中管理
由于响应式状态在 CS 交互层管理,你可以快速实现跨组件更新状态和刷新刷新数据,例如你可以在遇到以下场景时使用:
- 新增/编辑列表项后更新列表数据
- 在 App 中通知上一页刷新数据
- 编辑权限后刷新菜单栏
跨组件更新状态
通过 updateState
并传入 method 实例实现跨组件的更新响应式状态,此外,你还可以让 CS 交互层管理自定义的状态,让自定义的状态也支持跨组件更新。
跨组件刷新数据
有两种方式可以实现跨组件刷新数据。
- 通过
useFetcher
并传入 method 实例,它将会重新请求数据并更新这个 method 实例对应的响应式状态。 - 跨组件触发 useHooks 的 actions 完成数据的刷新,具体请参考action 委托中间件
响应数据集中管理
当开启了响应数据缓存后,CS 交互层将会按一定规则缓存响应数据,相同请求将会复用缓存数据来提升性能,具体请参考响应缓存章节。此外,你还可以预测用户接下来将要访问的数据,使用 useFetcher
预先请求数据并放在缓存中。
缓存时效性
有一个大家很关心的问题,如何保证缓存的时效性呢?alova 也提供了多种方式来处理缓存的时效性。