SvelteKit中如何通过load函数加载额外数据?
SvelteKit 加载更多场景的最佳实践(无URL参数)
1. 抽离统一的数据获取逻辑
将数据请求逻辑提取到独立的公共模块中,确保页面的load函数和组件内的加载更多逻辑使用同一套代码,从根源避免数据不一致问题。
示例:创建src/lib/data/fetchPosts.ts
export async function fetchPosts(top: number, skip: number) { // 替换为你的实际数据请求逻辑,比如调用后端API const res = await fetch(`/api/posts?top=${top}&skip=${skip}`); if (!res.ok) throw new Error('加载数据失败'); return res.json(); }
2. 用load函数初始化首屏数据
在+page.ts的load函数中调用公共逻辑,获取首屏数据并传递给页面组件,利用SvelteKit的服务端渲染/预渲染能力优化首屏体验。
示例:src/routes/posts/+page.ts
import { fetchPosts } from '$lib/data/fetchPosts'; export async function load() { const pageSize = 10; const initialPosts = await fetchPosts(pageSize, 0); return { initialPosts, pageSize }; }
3. 组件内实现增量加载逻辑
在+page.svelte中,基于load返回的初始数据初始化本地状态,点击「加载更多」时调用公共函数获取增量数据并合并,同时处理加载状态避免重复请求。
示例:src/routes/posts/+page.svelte
<script lang="ts"> import type { PageData } from './$types'; import { fetchPosts } from '$lib/data/fetchPosts'; export let data: PageData; let skip = $state(data.pageSize); // 初始跳过首屏已加载的数量 let posts = $state([...data.initialPosts]); let isLoading = $state(false); let hasMore = $state(true); async function loadMore() { if (isLoading || !hasMore) return; isLoading = true; try { const newPosts = await fetchPosts(data.pageSize, skip); posts = [...posts, ...newPosts]; skip += data.pageSize; // 判断是否还有更多数据 hasMore = newPosts.length === data.pageSize; } catch (err) { console.error('加载更多失败', err); } finally { isLoading = false; } } </script> <div class="post-list"> {#each posts as post (post.id)} <div class="post-item"> <h3>{post.title}</h3> <p>{post.content}</p> </div> {/each} </div> {#if hasMore} <button on:click={loadMore} disabled={isLoading} class="load-more-btn" > {isLoading ? '加载中...' : '加载更多'} </button> {:else} <p>没有更多数据了</p> {/if}
关键说明
- SvelteKit并未禁止组件内发起数据请求,首屏数据用
load获取是为了利用其SSR/SSG能力,而交互型的增量加载(如加载更多)完全适合在组件内处理。 - 通过抽离公共逻辑,确保
load和组件内的请求逻辑一致,从根本上避免数据不一致的问题。 - 若需要全局数据同步(比如其他页面修改了数据,当前页面需要刷新),可以结合
depends和invalidate机制,但这不属于加载更多的常规场景。
内容的提问来源于stack exchange,提问作者Subby
相关产品推荐
相关产品推荐

