如果你想阻止某个查询自动执行,可以使用 enabled = false 选项。enabled 选项也接受返回布尔值的回调函数。
当 enabled 为 false 时:
TypeScript 用户可能更倾向于使用 skipToken 作为 enabled = false 的替代方案
<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 选项不仅能永久禁用查询,还可以在后续启用/禁用。典型场景是筛选表单——只有当用户输入筛选值后才发起首次请求:
<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),
// ⬇️ 当筛选条件为空时禁用查询
enabled: isEnabled,
})
</script>
<template>
<span v-if="data">筛选条件已设置且数据已加载!</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),
// ⬇️ 当筛选条件为空时禁用查询
enabled: isEnabled,
})
</script>
<template>
<span v-if="data">筛选条件已设置且数据已加载!</span>
</template>
惰性查询会从一开始就处于 status: 'pending' 状态,因为 pending 表示尚无数据。虽然这在技术上是正确的,但由于我们并未实际获取数据(查询未被启用),你可能无法用这个标志来显示加载状态。
如果使用禁用或惰性查询,可以改用 isLoading 标志。这是一个衍生标志,由以下公式计算得出:
isPending && isFetching
因此只有当查询首次获取数据时,该标志才会为 true。
如果使用 TypeScript,可以通过 skipToken 禁用查询。这在需要基于条件禁用查询,同时保持类型安全时非常有用。
重要提示:useQuery 返回的 refetch 无法与 skipToken 配合使用。除此之外,skipToken 的行为与 enabled: false 完全一致。
<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],
// ⬇️ 当筛选条件未定义或为空时禁用查询
queryFn: queryFn,
})
</script>
<template>
<span v-if="data">筛选条件已设置且数据已加载!</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],
// ⬇️ 当筛选条件未定义或为空时禁用查询
queryFn: queryFn,
})
</script>
<template>
<span v-if="data">筛选条件已设置且数据已加载!</span>
</template>