查询是对异步数据源的声明性依赖,它与唯一的键相关联。查询可以与任何基于 Promise 的方法(包括 GET 和 POST 方法)一起使用,以从服务器获取数据。如果你的方法修改了服务器上的数据,我们建议改用突变。
要在你的组件或自定义 Hook 中订阅查询,请调用 useQuery Hook,至少需要
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">Loading...</span>
<span v-else-if="isError">Error: {{ error.message }}</span>
<!-- We can assume by this point that `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">Loading...</span>
<span v-else-if="isError">Error: {{ error.message }}</span>
<!-- We can assume by this point that `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'">Loading...</span>
<span v-else-if="status === 'error'">Error: {{ error.message }}</span>
<!-- also status === 'success', but "else" logic works, too -->
<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'">Loading...</span>
<span v-else-if="status === 'error'">Error: {{ error.message }}</span>
<!-- also status === 'success', but "else" logic works, too -->
<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 属性,它具有以下选项
后台重新获取和 stale-while-revalidate 逻辑使得 status 和 fetchStatus 的所有组合都成为可能。例如
因此请记住,查询可能处于 pending 状态,但实际上并未获取数据。作为经验法则