注意:Vue Query 的 Suspense 模式目前處於實驗階段,與 Vue 本身的 Suspense 功能相同。這些 API 將會變更,除非您將 Vue 和 Vue Query 的版本鎖定在相互兼容的修補版本,否則不應在生產環境中使用。
Vue Query 也能與 Vue 的新 Suspense API 搭配使用。
為此,您需要使用 Vue 提供的 Suspense 元件來包裹您的可暫停元件 (suspendable component)。
<script setup>
import SuspendableComponent from './SuspendableComponent.vue'
</script>
<template>
<Suspense>
<template #default>
<SuspendableComponent />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
</template>
<script setup>
import SuspendableComponent from './SuspendableComponent.vue'
</script>
<template>
<Suspense>
<template #default>
<SuspendableComponent />
</template>
<template #fallback>
<div>Loading...</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>
預設情況下,Vue Query 在 suspense 模式下無需額外配置,就能完美作為渲染時擷取 (Fetch-on-render) 解決方案。這意味著當您的元件嘗試掛載時,它們會觸發查詢擷取並暫停,但只有在您導入並掛載它們後才會執行。如果您想進一步提升並實現隨擷取隨渲染 (Render-as-you-fetch) 模式,我們建議在路由回調和/或用戶互動事件上實作預擷取 (Prefetching),以便在元件掛載前開始載入查詢,甚至能在您開始導入或掛載其父元件之前就進行。