跳到主要内容
版本:v2

数据拉取

当你有以下需求时:

  1. 预加载后续流程中将会使用到的数据并存放在缓存中,让用户不再等待数据加载的过程;
  2. 便捷地实现跨页面更新数据(类似全局状态),例如修改 todo 列表的某一项后重新拉取最新数据,响应后将刷新界面。

useFetcher就是用于实现以上场景的 hook,通过它获取的响应数据不能直接接收到,但通过它拉取的数据除了会更新缓存外还会更新对应的状态,从而重新渲染视图。

预加载数据

我们来实现一个分页列表中,自动预加载下一页数据,在预加载数据前请确保使用的 Method 实例已开启了缓存。

<template>
<div v-if="fetching">Fetching...</div>
<!-- 列表视图 -->
</template>

<script setup>
// method实例创建函数
const getTodoList = currentPage => {
return alovaInstance.Get('/todo/list', {
localCache: 60000,
params: {
currentPage,
pageSize: 10
}
});
};

const {
// fetching属性与loading相同,发送拉取请求时为true,请求结束后为false
fetching,
error,
onSuccess,
onError,
onComplete,

// 调用fetch后才会发送请求拉取数据,可以重复调用fetch多次拉取不同接口的数据
fetch
} = useFetcher({
updateState: false
});

const currentPage = ref(1);
const { data, onSuccess } = useWatcher(() => getTodoList(currentPage.value), [currentPage], {
immediate: true
});

// 在当前页加载成功后,传入下一页的method实例,即可预拉取下一页的数据
onSuccess(() => {
fetch(getTodoList(currentPage.value + 1));
});
</script>
注意

以上示例在调用useFetcher时设置了updateState为 false,这是因为默认情况下 fetch 时会自动触发跨组件更新状态,导致视图重新渲染,在预拉取的数据与当前请求的数据为同一份data时可以关闭它,以免影响视图错误。

跨模块/组件更新视图

下面我们来实现修改一条 todo 数据,并重新拉取最新的 todo 列表数据,让视图更新。我们可能并不知道 todo 列表当前位于第几页,此时在使用fetch函数时可以使用method 匹配器来动态拉取当前页的数据。

method 匹配器是用于,在已请求过的 method 实例中,查找符合条件的 method 实例。

首先,为 todo 列表的 method 实例设置名称,用于在无法直接指定 Method 实例时,过滤出需要的 Method 实例。

api/todoList.js
const getTodoList = currentPage => {
return alovaInstance.Get('/todo/list', {
name: 'todoList',
params: {
currentPage,
pageSize: 10
}
});
};

然后在EditTodo组件中,通过fetch函数在已请求过的 Method 实例中,动态查找最后一个 name 为todoList进行数据拉取。

EditTodo Component
const { fetch } = useFetcher();

// 在事件中触发数据拉取
const handleSubmit = () => {
// 提交数据...
await fetch({
name: 'todoList',
filter: (method, index, ary) => {
// 返回true来指定需要拉取的Method实例
return index === ary.length - 1;
}
});
};
注意事项

useFetcher 请求完成后只更新缓存,且如果发现这个 Method 实例在之前使用过 useHook 请求过,那么也会更新这个 useHook 创建的data状态,从而保证页面数据一致,这是useFetcher用于跨模块/组件更新视图的保证。

更多 method 匹配器的使用方法见 method 匹配器

强制发送请求

useRequestuseWatcher相同,更多请阅读强制请求

绑定响应回调

useFetcher 也支持绑定onSuccess/onError/onComplete回调函数。

const { onSuccess, onError, onComplete } = useFetcher();

具体请阅读响应处理

send 函数参数传递规则

useRequestuseWatcher不同的是,fetch 函数的自定义参数是从第二个参数开始的,它们也将分别被事件回调和force函数接收。

const { onSuccess, fetch } = useFetcher();
onSuccess(({ sendArgs }) => {
// sendArgs的值为['test arg']
});

fetch(getTodoList(), 'test arg');

具体请阅读send 函数参数传递规则

useRequest 与 useFetcher 对比

  1. useFetcher 不返回data字段,预拉取的数据将保存在缓存中,以及更新对应位置的状态数据;
  2. loading改名为了fetching;
  3. 没有send函数,但多了一个fetch函数,可以重复利用 fetch 函数拉取不同接口的数据,此时你可以使用 fetchingerror 状态统一渲染视图,从而达到统一处理的目的;