SvelteKit 默认使用 SSR 渲染路由。因此,您需要在服务器上禁用查询。否则,即使 HTML 已发送到客户端,您的查询仍将在服务器上异步执行。
推荐的方法是在您的 QueryClient
对象中使用 SvelteKit 的 browser
模块。这不会禁用 queryClient.prefetchQuery()
,该方法在以下解决方案之一中使用。
src/routes/+layout.svelte
<script lang="ts">
import { browser } from '$app/environment'
import { QueryClient, QueryClientProvider } from '@tanstack/svelte-query'
const queryClient = new QueryClient({
defaultOptions: {
queries: {
enabled: browser,
},
},
})
</script>
<QueryClientProvider client={queryClient}>
<slot />
</QueryClientProvider>
<script lang="ts">
import { browser } from '$app/environment'
import { QueryClient, QueryClientProvider } from '@tanstack/svelte-query'
const queryClient = new QueryClient({
defaultOptions: {
queries: {
enabled: browser,
},
},
})
</script>
<QueryClientProvider client={queryClient}>
<slot />
</QueryClientProvider>
Svelte Query 支持两种在服务器上预取数据并通过 SvelteKit 传递给客户端的方式。
如果您希望查看理想的 SSR 设置,请查看 SSR 示例。
initialData
结合 SvelteKit 的 load
,您可以将服务器端加载的数据传递到 createQuery
的 initialData
选项中
src/routes/+page.ts
export async function load() {
const posts = await getPosts()
return { posts }
}
export async function load() {
const posts = await getPosts()
return { posts }
}
src/routes/+page.svelte
<script>
import { createQuery } from '@tanstack/svelte-query'
import type { PageData } from './$types'
export let data: PageData
const query = createQuery({
queryKey: ['posts'],
queryFn: getPosts,
initialData: data.posts,
})
</script>
<script>
import { createQuery } from '@tanstack/svelte-query'
import type { PageData } from './$types'
export let data: PageData
const query = createQuery({
queryKey: ['posts'],
queryFn: getPosts,
initialData: data.posts,
})
</script>
优点
+page.ts
/+layout.ts
和 +page.server.ts
/+layout.server.ts
加载函数缺点
createQuery
,则需要将 initialData
传递到该位置createQuery
,则需要将 initialData
传递给所有这些位置dataUpdatedAt
以及确定查询是否需要重新获取是基于页面加载的时间prefetchQuery
Svelte Query 支持在服务器上预取查询。使用下面的设置,您可以在数据发送到用户浏览器之前获取数据并将其传递到 QueryClientProvider 中。因此,此数据已在缓存中可用,并且客户端不会发生初始获取。
src/routes/+layout.ts
import { browser } from '$app/environment'
import { QueryClient } from '@tanstack/svelte-query'
export async function load() {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
enabled: browser,
},
},
})
return { queryClient }
}
import { browser } from '$app/environment'
import { QueryClient } from '@tanstack/svelte-query'
export async function load() {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
enabled: browser,
},
},
})
return { queryClient }
}
src/routes/+layout.svelte
<script lang="ts">
import { QueryClientProvider } from '@tanstack/svelte-query'
import type { LayoutData } from './$types'
export let data: LayoutData
</script>
<QueryClientProvider client={data.queryClient}>
<slot />
</QueryClientProvider>
<script lang="ts">
import { QueryClientProvider } from '@tanstack/svelte-query'
import type { LayoutData } from './$types'
export let data: LayoutData
</script>
<QueryClientProvider client={data.queryClient}>
<slot />
</QueryClientProvider>
src/routes/+page.ts
export async function load({ parent, fetch }) {
const { queryClient } = await parent()
// You need to use the SvelteKit fetch function here
await queryClient.prefetchQuery({
queryKey: ['posts'],
queryFn: async () => (await fetch('/api/posts')).json(),
})
}
export async function load({ parent, fetch }) {
const { queryClient } = await parent()
// You need to use the SvelteKit fetch function here
await queryClient.prefetchQuery({
queryKey: ['posts'],
queryFn: async () => (await fetch('/api/posts')).json(),
})
}
src/routes/+page.svelte
<script lang="ts">
import { createQuery } from '@tanstack/svelte-query'
// This data is cached by prefetchQuery in +page.ts so no fetch actually happens here
const query = createQuery({
queryKey: ['posts'],
queryFn: async () => (await fetch('/api/posts')).json(),
})
</script>
<script lang="ts">
import { createQuery } from '@tanstack/svelte-query'
// This data is cached by prefetchQuery in +page.ts so no fetch actually happens here
const query = createQuery({
queryKey: ['posts'],
queryFn: async () => (await fetch('/api/posts')).json(),
})
</script>
优点
dataUpdatedAt
缺点
+page.server.ts
/+layout.server.ts
加载函数(但是,与 TanStack Query 一起使用的 API 无论如何都需要完全暴露给浏览器)