译零 TransZero · TanStack Query 中文文档
主站

禁用/暂停查询

更新于 2026-11-02 Vue 查看英文原文 ↗

如果你希望禁用某个查询,使其不自动执行,可以使用 enabled = false 选项。enabled 选项还支持传入一个返回布尔值的回调函数。

当 enabled 为 false 时:

  • 如果查询已缓存数据,则查询将初始化为 status === 'success' 或 isSuccess 状态。
  • 如果查询没有缓存数据,则查询将从 status === 'pending' 和 fetchStatus === 'idle' 状态开始。
  • 查询在挂载时不会自动拉取。
  • 查询不会在后台自动重新拉取。
  • 查询会忽略查询客户端的 invalidateQueries 和 refetchQueries 调用(这些调用通常会触发查询重新拉取)。
  • 通过 useQuery 返回的 refetch 可用于手动触发查询拉取。但该方法不适用于 skipToken。

使用 TypeScript 的用户可能更倾向于使用 skipToken 作为 enabled = false 的替代方案。

HTML
1<script setup>2import { useQuery } from '@tanstack/vue-query'34const { isLoading, isError, data, error, refetch, isFetching } = useQuery({5  queryKey: ['todos'],6  queryFn: fetchTodoList,7  enabled: false,8})9</script>10 11<template>12  <button @click="refetch()">Fetch Todos</button>13  <span v-if="isLoading">Loading...</span>14  <span v-else-if="isError">Error: {{ error?.message }}</span>15  <div v-else-if="data">16    <span v-if="isFetching">Fetching...</span>17    <ul>18      <li v-for="todo in data" :key="todo.id">{{ todo.title }}</li>19    </ul>20  </div>21  <span v-else>Not ready...</span>22</template>

永久禁用查询会使你无法使用 TanStack Query 提供的许多优秀功能(例如后台重新拉取),而且这也不是符合惯用法的做法。它会迫使你从声明式方式(定义查询应在何时运行)转向命令式方式(点击此处时才拉取)。此外,你无法向 refetch 传递参数。很多时候,你真正需要的只是一个延迟查询(lazy query),即推迟初始拉取操作:

延迟查询(Lazy Queries)

enabled 选项不仅可以用于永久禁用查询,还可以在后续某个时间点启用或禁用查询。一个典型示例是筛选表单:你仅希望在用户输入筛选值后才发起首次请求:

HTML
1<script setup>2import { useQuery } from '@tanstack/vue-query'34const filter = ref('')5const isEnabled = computed(() => !!filter.value)6const { data } = useQuery({7  queryKey: ['todos', filter],8  queryFn: () => fetchTodos(filter),9  // ⬇️ disabled as long as the filter is empty10  enabled: isEnabled,11})12</script>13 14<template>15  <span v-if="data">Filter was set and data is here!</span>16</template>

isLoading(此前名为 isInitialLoading)

延迟查询从一开始就会处于 status: 'pending' 状态,因为 pending 表示尚无数据。从技术上讲这是正确的;但由于此时并未实际拉取任何数据(查询尚未 启用),因此你很可能无法使用该标志来显示加载指示器。

如果你正在使用已禁用或延迟的查询,可改用 isLoading 标志。这是一个派生标志,其计算逻辑为:

isPending && isFetching

因此,仅当查询当前正在进行首次拉取时,该标志才为 true。

使用 skipToken 类型安全地禁用查询

如果你正在使用 TypeScript,可以使用 skipToken 来禁用查询。当你需要根据某个条件禁用查询,同时又希望保持类型安全性时,此方法非常有用。

重要提示:useQuery 返回的 refetch 不适用于 skipToken。对使用 skipToken 的查询调用 refetch() 将导致 Missing queryFn 错误,因为此时不存在有效的查询函数可供执行。如需手动触发查询,请考虑改用 enabled: false,它能确保 refetch() 正常工作。除这一限制外,skipToken 的行为与 enabled: false 完全一致。

HTML
1<script setup>2import { useQuery, skipToken } from '@tanstack/vue-query'34const filter = ref('')5const queryFn = computed(() =>6  !!filter.value ? () => fetchTodos(filter) : skipToken,7)8const { data } = useQuery({9  queryKey: ['todos', filter],10  // ⬇️ disabled as long as the filter is undefined or empty11  queryFn: queryFn,12})13</script>14 15<template>16  <span v-if="data">Filter was set and data is here!</span>17</template>

本页为 TanStack Query 文档(Vue 版)的非官方中文翻译,原文由上游团队维护,遵循 MIT 许可。 译文如有偏差,以英文原文为准。

译自上游 59d11de