useInfiniteQuery
概述
1function useInfiniteQuery<TQueryFnData, TError = Error, TData = InfiniteData<TQueryFnData, unknown>, TQueryKey extends readonly unknown[] = readonly unknown[], TPageParam = unknown>(options: MaybeRefOrGetter<DefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>, queryClient?: QueryClient): UseInfiniteQueryReturnType<TData, TError>;2function useInfiniteQuery<TQueryFnData, TError = Error, TData = InfiniteData<TQueryFnData, unknown>, TQueryKey extends readonly unknown[] = readonly unknown[], TPageParam = unknown>(options: MaybeRefOrGetter<UndefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>, queryClient?: QueryClient): UseInfiniteQueryReturnType<TData, TError>;3function useInfiniteQuery<TQueryFnData, TError = Error, TData = InfiniteData<TQueryFnData, unknown>, TQueryKey extends readonly unknown[] = readonly unknown[], TPageParam = unknown>(options: MaybeRefOrGetter<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>, queryClient?: QueryClient): UseInfiniteQueryReturnType<TData, TError>;MaybeRefOrGetter→UseInfiniteQueryReturnType:useInfiniteQuery的选项与useQuery完全相同,额外增加了initialPageParam、getNextPageParam、getPreviousPageParam和maxPages。MaybeRefOrGetter→UseInfiniteQueryReturnType:useInfiniteQuery的选项与useQuery完全相同,额外增加了initialPageParam、getNextPageParam、getPreviousPageParam和maxPages。MaybeRefOrGetter→UseInfiniteQueryReturnType:当initialData是否存在无法在编译期静态确定时(例如,条件式构建的ref/响应式对象,而非普通对象字面量),使用该后备重载。应优先选用其他重载,因为它们能直接根据initialData推断data是否可为undefined。
调用签名
1function useInfiniteQuery<TQueryFnData, TError = Error, TData = InfiniteData<TQueryFnData, unknown>, TQueryKey extends readonly unknown[] = readonly unknown[], TPageParam = unknown>(options: MaybeRefOrGetter<DefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>, queryClient?: QueryClient): UseInfiniteQueryReturnType<TData, TError>;定义于:packages/vue-query/src/useInfiniteQuery.ts:127
useInfiniteQuery 的选项与 useQuery 完全相同,额外增加了 initialPageParam、getNextPageParam、getPreviousPageParam 和 maxPages。
当 initialData 已知被定义时,将选择此重载,因此所得 data 永远不会是 undefined(除非某个 select 将 TData 更改为包含 undefined 的类型)。
enabled 会自动追踪响应式依赖,其形式可以是 ref、普通值或响应式 getter(() => ...)。queryKey 通过 ref 响应数组本身,或通过 ref 和响应式 getter 响应各个数组项——数组本身不能是裸的 getter。
类型参数
TQueryFnData
TQueryFnData
TError
TError = Error
TData
TData = InfiniteData<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
参数
options
MaybeRefOrGetter<DefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>
要使用的 DefinedInitialDataInfiniteOptions —— 即所有可传给 useInfiniteQuery 的选项,且 initialData 已知被定义。
queryClient?
使用此参数可指定自定义 QueryClient;否则将使用 VueQueryPlugin 提供的 QueryClient。
返回值
UseInfiniteQueryReturnType<TData, TError>
与 useQuery 的属性相同,额外增加了 fetchNextPage、fetchPreviousPage、hasNextPage、hasPreviousPage、isFetchingNextPage 和 isFetchingPreviousPage。只要 select 不将 TData 改为偏离其默认 InfiniteData<TQueryFnData> 形状的类型,data.value.pages 和 data.value.pageParams 也会被添加。
备注
请注意,命令式拉取调用(例如 fetchNextPage)可能干扰默认的重新拉取行为,导致数据过时。务必仅在响应用户操作时调用这些函数,或添加类似 hasNextPage && !isFetching 的条件判断。
示例
1<script setup lang="ts">2import { useInfiniteQuery } from '@tanstack/vue-query'34// `data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the5// list stays visible alongside the error.6const { data, isError, error } = useInfiniteQuery({7 queryKey: ['projects'],8 queryFn: ({ pageParam }) => fetchProjects(pageParam),9 initialPageParam: 0,10 getNextPageParam: (lastPage) => lastPage.nextId,11 initialData: { pages: [], pageParams: [] },12})13</script>14 15<template>16 <span v-if="isError">Error: {{ error.message }}</span>17 <ul>18 <template v-for="page in data.pages" :key="page.nextId">19 <li v-for="project in page.projects" :key="project.id">{{ project.name }}</li>20 </template>21 </ul>22</template>调用签名
1function useInfiniteQuery<TQueryFnData, TError = Error, TData = InfiniteData<TQueryFnData, unknown>, TQueryKey extends readonly unknown[] = readonly unknown[], TPageParam = unknown>(options: MaybeRefOrGetter<UndefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>, queryClient?: QueryClient): UseInfiniteQueryReturnType<TData, TError>;定义于:packages/vue-query/src/useInfiniteQuery.ts:258
useInfiniteQuery 的选项与 useQuery 完全相同,额外增加了 initialPageParam、getNextPageParam、getPreviousPageParam 和 maxPages。
enabled 会自动追踪响应式依赖,其形式可以是 ref、普通值或响应式 getter(() => ...)。queryKey 通过 ref 响应数组本身,或通过 ref 和响应式 getter 响应各个数组项——数组本身不能是裸的 getter。
类型参数
TQueryFnData
TQueryFnData
TError
TError = Error
TData
TData = InfiniteData<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
参数
options
MaybeRefOrGetter<UndefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>
要使用的 UndefinedInitialDataInfiniteOptions —— 即所有可传给 useInfiniteQuery 的选项。
queryClient?
使用此参数可指定自定义 QueryClient;否则将使用 VueQueryPlugin 提供的 QueryClient。
返回值
UseInfiniteQueryReturnType<TData, TError>
与 useQuery 的属性相同,额外增加了 fetchNextPage、fetchPreviousPage、hasNextPage、hasPreviousPage、isFetchingNextPage 和 isFetchingPreviousPage。只要 select 不将 TData 改为偏离其默认 InfiniteData<TQueryFnData> 形状的类型,data.value.pages 和 data.value.pageParams 也会被添加。
备注
请注意,命令式拉取调用(例如 fetchNextPage)可能干扰默认的重新拉取行为,导致数据过时。务必仅在响应用户操作时调用这些函数,或添加类似 hasNextPage && !isFetching 的条件判断。
示例
通过「加载更多」按钮点击拉取下一页:
1<script setup lang="ts">2import { useInfiniteQuery } from '@tanstack/vue-query'34const {5 data,6 isPending,7 isError,8 error,9 fetchNextPage,10 hasNextPage,11 isFetching,12 isFetchingNextPage,13} = useInfiniteQuery({14 queryKey: ['projects'],15 queryFn: ({ pageParam }) => fetchProjects(pageParam),16 initialPageParam: 0,17 getNextPageParam: (lastPage) => lastPage.nextId,18})19</script>20 21<template>22 <span v-if="isPending">Loading...</span>23 <span v-else-if="isError">Error: {{ error.message }}</span>24 <template v-else>25 <ul>26 <template v-for="page in data.pages" :key="page.nextId">27 <li v-for="project in page.projects" :key="project.id">{{ project.name }}</li>28 </template>29 </ul>30 <button @click="fetchNextPage()" :disabled="!hasNextPage || isFetching">31 {{ isFetchingNextPage ? 'Loading more...' : hasNextPage ? 'Load More' : 'Nothing more to load' }}32 </button>33 </template>34</template>利用 IntersectionObserver 在列表末尾的哨兵元素上自动拉取下一页(随用户滚动触发):
1<script setup lang="ts">2import { onUnmounted, ref, watch } from 'vue'3import { useInfiniteQuery } from '@tanstack/vue-query'45const {6 data,7 isPending,8 isError,9 error,10 fetchNextPage,11 hasNextPage,12 isFetching,13 isFetchingNextPage,14} = useInfiniteQuery({15 queryKey: ['projects'],16 queryFn: ({ pageParam }) => fetchProjects(pageParam),17 initialPageParam: 0,18 getNextPageParam: (lastPage) => lastPage.nextId,19})2021const sentinel = ref<HTMLElement>()22let observer: IntersectionObserver | undefined2324watch(sentinel, (el) => {25 observer?.disconnect()26 if (el == null) return2728 observer = new IntersectionObserver(([entry]) => {29 if (entry?.isIntersecting && hasNextPage.value && !isFetching.value) {30 fetchNextPage()31 }32 })33 observer.observe(el)34})3536onUnmounted(() => observer?.disconnect())37</script>38 39<template>40 <span v-if="isPending">Loading...</span>41 <span v-else-if="isError">Error: {{ error.message }}</span>42 <template v-else>43 <ul>44 <template v-for="page in data.pages" :key="page.nextId">45 <li v-for="project in page.projects" :key="project.id">{{ project.name }}</li>46 </template>47 </ul>48 <div ref="sentinel">{{ isFetchingNextPage ? 'Loading more...' : '' }}</div>49 </template>50</template>调用签名
1function useInfiniteQuery<TQueryFnData, TError = Error, TData = InfiniteData<TQueryFnData, unknown>, TQueryKey extends readonly unknown[] = readonly unknown[], TPageParam = unknown>(options: MaybeRefOrGetter<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>, queryClient?: QueryClient): UseInfiniteQueryReturnType<TData, TError>;定义于:packages/vue-query/src/useInfiniteQuery.ts:351
当 initialData 是否存在无法在编译期静态确定时(例如,条件式构建的 ref/响应式对象,而非普通对象字面量),使用该后备重载。应优先选用其他重载,因为它们能直接根据 initialData 推断 data 是否可为 undefined。
enabled 会自动追踪响应式依赖,其形式可以是 ref、普通值或响应式 getter(() => ...)。queryKey 通过 ref 响应数组本身,或通过 ref 和响应式 getter 响应各个数组项——数组本身不能是裸的 getter。
类型参数
TQueryFnData
TQueryFnData
TError
TError = Error
TData
TData = InfiniteData<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
参数
options
MaybeRefOrGetter<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>
一个 ref、普通值或响应式 getter,用于解析出要使用的 UseInfiniteQueryOptions。
queryClient?
使用此参数可指定自定义 QueryClient;否则将使用 VueQueryPlugin 提供的 QueryClient。
返回值
UseInfiniteQueryReturnType<TData, TError>
与 useQuery 的属性相同,额外增加了 fetchNextPage、fetchPreviousPage、hasNextPage、hasPreviousPage、isFetchingNextPage 和 isFetchingPreviousPage。
示例
传递整个 options 的 getter,使 maxPages 可响应存储在别处的设置(而不仅限于 queryKey):
1<script setup lang="ts">2import { useInfiniteQuery } from '@tanstack/vue-query'34const props = defineProps<{ projectId: number; maxPages: number }>()56const { data } = useInfiniteQuery(() => ({7 queryKey: ['project', props.projectId, 'issues'],8 queryFn: ({ pageParam }) => fetchIssues(props.projectId, pageParam),9 initialPageParam: 0,10 getNextPageParam: (lastPage) => lastPage.nextId,11 maxPages: props.maxPages,12}))13</script>14 15<template>16 <template v-for="page in data?.pages" :key="page.nextId">17 <li v-for="issue in page.issues" :key="issue.id">{{ issue.title }}</li>18 </template>19</template>一个在 postId 被设置前保持禁用且类型安全的查询——将 skipToken 作为 queryFn 传入,而非直接设置 enabled: false。这需要整个 options 的 getter:queryFn 本身并非响应式,因此 getter 才能在 props.postId 每次变更时重新求值:
1<script setup lang="ts">2import { skipToken, useInfiniteQuery } from '@tanstack/vue-query'34const props = defineProps<{ postId: string | undefined }>()56// Use `isLoading`, not `isPending`, so the loading state doesn't show while the query is disabled.7const { data, isLoading, isError, error } = useInfiniteQuery(() => {8 const postId = props.postId9 return {10 queryKey: ['post', postId, 'comments'],11 queryFn:12 postId != null13 ? ({ pageParam }) => fetchComments(postId, pageParam)14 : skipToken,15 initialPageParam: 0,16 getNextPageParam: (lastPage) => lastPage.nextId,17 }18})19</script>20 21<template>22 <span v-if="props.postId == null">Select a post</span>23 <span v-else-if="isLoading">Loading...</span>24 <span v-else-if="isError">Error: {{ error.message }}</span>25 <ul v-else>26 <template v-for="page in data.pages" :key="page.nextId">27 <li v-for="comment in page.comments" :key="comment.id">{{ comment.text }}</li>28 </template>29 </ul>30</template>参数
options
MaybeRefOrGetter<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>>
一个 ref、普通值或响应式 getter,用于解析出要使用的 UseInfiniteQueryOptions。
queryClient?
使用此参数可指定自定义 QueryClient;否则将使用 VueQueryPlugin 提供的 QueryClient。
返回值
UseInfiniteQueryReturnType<TData, TError>
与 useQuery 的属性相同,额外增加了 fetchNextPage、fetchPreviousPage、hasNextPage、hasPreviousPage、isFetchingNextPage 和 isFetchingPreviousPage。