禁用/暂停查询

如果您希望禁用查询自动运行,可以使用 enabled = false 选项。 enabled 选项也接受返回布尔值的回调函数。

enabledfalse

  • 如果查询有缓存数据,则查询将在 status === 'success'isSuccess 状态下初始化。
  • 如果查询没有缓存数据,则查询将在 status === 'pending'fetchStatus === 'idle' 状态下启动。
  • 查询不会在挂载时自动获取数据。
  • 查询不会在后台自动重新获取数据。
  • 查询将忽略查询客户端的 invalidateQueriesrefetchQueries 调用,这些调用通常会导致查询重新获取数据。
  • useQuery 返回的 refetch 可用于手动触发查询以获取数据。但是,它不适用于 skipToken

TypeScript 用户可能更喜欢使用 skipToken 作为 enabled = false 的替代方案。

vue
<script setup>
import { useQuery } from '@tanstack/vue-query'

const { isLoading, isError, data, error, refetch, isFetching } = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
  enabled: false,
})
</script>

<template>
  <button @click="refetch">Fetch Todos</button>
  <span v-if="isIdle">Not ready...</span>
  <span v-else-if="isError">Error: {{ error.message }}</span>
  <div v-else-if="data">
    <span v-if="isFetching">Fetching...</span>
    <ul>
      <li v-for="todo in data" :key="todo.id">{{ todo.title }}</li>
    </ul>
  </div>
</template>
<script setup>
import { useQuery } from '@tanstack/vue-query'

const { isLoading, isError, data, error, refetch, isFetching } = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
  enabled: false,
})
</script>

<template>
  <button @click="refetch">Fetch Todos</button>
  <span v-if="isIdle">Not ready...</span>
  <span v-else-if="isError">Error: {{ error.message }}</span>
  <div v-else-if="data">
    <span v-if="isFetching">Fetching...</span>
    <ul>
      <li v-for="todo in data" :key="todo.id">{{ todo.title }}</li>
    </ul>
  </div>
</template>

永久禁用查询会放弃 TanStack Query 提供的许多强大功能(例如后台重新获取),而且这不是惯用的方法。它将您从声明式方法(定义查询何时应运行的依赖项)带入命令式模式(每当我在此处单击时获取)。也不可能将参数传递给 refetch。通常,您想要的只是一个延迟初始获取的懒加载查询

懒加载查询

enabled 选项不仅可以用于永久禁用查询,还可以用于稍后启用/禁用它。一个很好的例子是过滤器表单,您只想在用户输入过滤器值后才触发第一个请求

vue
<script setup>
import { useQuery } from '@tanstack/vue-query'

const filter = ref('')
const isEnabled = computed(() => !!filter.value)
const { data } = useQuery({
  queryKey: ['todos', filter],
  queryFn: () => fetchTodos(filter),
  // ⬇️ disabled as long as the filter is empty
  enabled: isEnabled,
})
</script>

<template>
  <span v-if="data">Filter was set and data is here!</span>
</template>
<script setup>
import { useQuery } from '@tanstack/vue-query'

const filter = ref('')
const isEnabled = computed(() => !!filter.value)
const { data } = useQuery({
  queryKey: ['todos', filter],
  queryFn: () => fetchTodos(filter),
  // ⬇️ disabled as long as the filter is empty
  enabled: isEnabled,
})
</script>

<template>
  <span v-if="data">Filter was set and data is here!</span>
</template>

isLoading (之前: isInitialLoading)

懒加载查询从一开始就处于 status: 'pending' 状态,因为 pending 意味着尚无数据。从技术上讲这是正确的,但是,由于我们当前未获取任何数据(因为查询未启用),因此这也意味着您可能无法使用此标志来显示加载指示器。

如果您正在使用禁用或懒加载查询,则可以使用 isLoading 标志代替。它是一个派生标志,从以下内容计算得出

isPending && isFetching

因此,仅当查询当前首次获取数据时,它才为真。

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

如果您正在使用 TypeScript,则可以使用 skipToken 来禁用查询。当您想要根据条件禁用查询,但仍希望保持查询的类型安全时,这非常有用。

重要提示:来自 useQueryrefetch 不适用于 skipToken。除此之外,skipToken 的工作方式与 enabled: false 相同。

vue
<script setup>
import { useQuery, skipToken } from '@tanstack/vue-query'

const filter = ref('')
const queryFn = computed(() =>
  !!filter.value ? () => fetchTodos(filter) : skipToken,
)
const { data } = useQuery({
  queryKey: ['todos', filter],
  // ⬇️ disabled as long as the filter is undefined or empty
  queryFn: queryFn,
})
</script>

<template>
  <span v-if="data">Filter was set and data is here!</span>
</template>
<script setup>
import { useQuery, skipToken } from '@tanstack/vue-query'

const filter = ref('')
const queryFn = computed(() =>
  !!filter.value ? () => fetchTodos(filter) : skipToken,
)
const { data } = useQuery({
  queryKey: ['todos', filter],
  // ⬇️ disabled as long as the filter is undefined or empty
  queryFn: queryFn,
})
</script>

<template>
  <span v-if="data">Filter was set and data is here!</span>
</template>