查询是与唯一键绑定的、对异步数据源的声明式依赖。查询可用于任何基于 Promise 的方法(包括 GET 和 POST 方法)从服务器获取数据。如果你的方法会修改服务器数据,我们建议改用变更。
要在组件或自定义钩子中订阅查询,至少需要调用 useQuery 钩子并传入:
import { useQuery } from '@tanstack/vue-query'
const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
import { useQuery } from '@tanstack/vue-query'
const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
你提供的唯一键将在内部用于重新获取、缓存及在整个应用中共享查询。
useQuery 返回的查询结果包含所有与查询相关的信息,这些信息可用于模板渲染或其他数据处理场景:
const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
result 对象包含若干关键状态,理解这些状态对高效使用至关重要。查询在任意时刻只能处于以下一种状态:
除了这些主要状态,根据查询状态还可获取更多信息:
对于大多数查询,通常只需先检查 isPending 状态,再检查 isError 状态,最后即可认为数据已可用并渲染成功状态:
<script setup>
import { useQuery } from '@tanstack/vue-query'
const { isPending, isError, data, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
</script>
<template>
<span v-if="isPending">加载中...</span>
<span v-else-if="isError">错误: {{ error.message }}</span>
<!-- 此时可以认为 `isSuccess === true` -->
<ul v-else-if="data">
<li v-for="todo in data" :key="todo.id">{{ todo.title }}</li>
</ul>
</template>
<script setup>
import { useQuery } from '@tanstack/vue-query'
const { isPending, isError, data, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
</script>
<template>
<span v-if="isPending">加载中...</span>
<span v-else-if="isError">错误: {{ error.message }}</span>
<!-- 此时可以认为 `isSuccess === true` -->
<ul v-else-if="data">
<li v-for="todo in data" :key="todo.id">{{ todo.title }}</li>
</ul>
</template>
如果不习惯使用布尔值,也可以始终使用 status 状态:
<script setup>
import { useQuery } from '@tanstack/vue-query'
const { status, data, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
</script>
<template>
<span v-if="status === 'pending'">加载中...</span>
<span v-else-if="status === 'error'">错误: {{ error.message }}</span>
<!-- 同样可用 status === 'success',但 else 逻辑也适用 -->
<ul v-else-if="data">
<li v-for="todo in data" :key="todo.id">{{ todo.title }}</li>
</ul>
</template>
<script setup>
import { useQuery } from '@tanstack/vue-query'
const { status, data, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
</script>
<template>
<span v-if="status === 'pending'">加载中...</span>
<span v-else-if="status === 'error'">错误: {{ error.message }}</span>
<!-- 同样可用 status === 'success',但 else 逻辑也适用 -->
<ul v-else-if="data">
<li v-for="todo in data" :key="todo.id">{{ todo.title }}</li>
</ul>
</template>
如果你在访问 data 前已检查过 pending 和 error 状态,TypeScript 也会正确收窄 data 的类型。
除了 status 字段外,你还会获得一个额外的 fetchStatus 属性,其可选值为:
后台重新获取和"过时但可用"逻辑使得 status 和 fetchStatus 的所有组合都可能出现。例如:
因此要记住:查询可能处于 pending 状态但并未实际获取数据。简单来说: