注意:Vue Query 的 Suspense 模式是实验性的,与 Vue 的 Suspense 本身一样。这些 API 将会更改,并且不应在生产环境中使用,除非您将 Vue 和 Vue Query 版本都锁定到彼此兼容的补丁级别版本。
Vue Query 也可以与 Vue 的新 Suspense API 一起使用。
为此,您需要使用 Vue 提供的 Suspense 组件包装您的可暂停组件
<script setup>
import SuspendableComponent from './SuspendableComponent.vue'
</script>
<template>
<Suspense>
<template #default>
<SuspendableComponent />
</template>
<template #fallback>
<div>加载中...</div>
</template>
</Suspense>
</template>
<script setup>
import SuspendableComponent from './SuspendableComponent.vue'
</script>
<template>
<Suspense>
<template #default>
<SuspendableComponent />
</template>
<template #fallback>
<div>加载中...</div>
</template>
</Suspense>
</template>
并将可暂停组件中的 setup 函数更改为 async。然后,您可以使用 vue-query 提供的异步 suspense 函数。
<script>
import { defineComponent } from 'vue'
import { useQuery } from '@tanstack/vue-query'
const todoFetcher = async () =>
await fetch('https://jsonplaceholder.cypress.io/todos').then((response) =>
response.json(),
)
export default defineComponent({
name: 'SuspendableComponent',
async setup() {
const { data, suspense } = useQuery(['todos'], todoFetcher)
await suspense()
return { data }
},
})
</script>
<script>
import { defineComponent } from 'vue'
import { useQuery } from '@tanstack/vue-query'
const todoFetcher = async () =>
await fetch('https://jsonplaceholder.cypress.io/todos').then((response) =>
response.json(),
)
export default defineComponent({
name: 'SuspendableComponent',
async setup() {
const { data, suspense } = useQuery(['todos'], todoFetcher)
await suspense()
return { data }
},
})
</script>
开箱即用,suspense 模式下的 Vue Query 作为 Fetch-on-render 解决方案效果非常好,无需额外配置。这意味着当您的组件尝试挂载时,它们将触发查询获取并暂停,但仅在您导入并挂载它们之后。如果您想更进一步并实现 Render-as-you-fetch 模型,我们建议在路由回调和/或用户交互事件上实现预取,以便在挂载查询之前开始加载查询,甚至希望在开始导入或挂载其父组件之前。