You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为SvelteKit顶层+layout.ts的load函数添加加载指示器

解决SvelteKit顶层layout加载时显示加载指示器的问题

方法1:利用app.html添加初始加载指示器

在项目根目录的app.html中,在Svelte挂载容器内添加加载指示器,初始加载时会直接显示,直到SvelteKit完成数据加载并渲染组件:

<!-- app.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
	<meta charset="UTF-8">
	<title>%sveltekit.title%</title>
	<style>
		.loading-indicator {
			position: fixed;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
			display: flex;
			align-items: center;
			justify-content: center;
			font-size: 1.2rem;
			background: #fff;
		}
	</style>
</head>
<body>
	<div id="svelte">
		<div class="loading-indicator">正在加载中...</div>
	</div>
</body>
</html>

当SvelteKit完成+layout.ts的load函数并渲染根布局组件时,#svelte内的加载指示器会被替换为布局内容,无需额外隐藏逻辑。

方法2:流式处理load函数(分阶段渲染)

即使所有数据都是必需的,也可以让load函数先返回数据请求的Promise,让SvelteKit提前渲染布局并显示加载状态,等数据加载完成后再渲染完整内容:

// routes/+layout.ts
export async function load({ fetch }) {
	// 发起数据请求但不等待完成,直接返回Promise
	const fullDataPromise = fetch('/api/required-data').then(res => res.json());

	// 立即返回结果,触发布局渲染
	return { fullDataPromise };
}

在根+layout.svelte中使用await块控制渲染:

<!-- routes/+layout.svelte -->
<script>
	export let data;
</script>

{#await data.fullDataPromise}
	<div class="loading-indicator">正在加载中...</div>
{:then fullData}
	<main>
		<!-- 将数据传递给子页面 -->
		<slot {fullData} />
	</main>
{/await}

<style>
	.loading-indicator {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 1.2rem;
		background: #fff;
	}
</style>

这种方式既保证了所有数据最终可用,又能让用户立即看到加载反馈。

方法3:结合navigating store与初始加载判断

在根布局中监听导航状态,同时处理初始加载的特殊情况:

<!-- routes/+layout.svelte -->
<script>
	import { navigating, page } from '$app/stores';
	import { onMount } from 'svelte';

	let isLoading = true;

	onMount(() => {
		const unsubscribe = navigating.subscribe(nav => {
			isLoading = nav !== null;
		});

		// 初始加载完成后,手动判断数据是否就绪
		const checkLoaded = () => {
			if ($page.data) {
				isLoading = false;
			} else {
				setTimeout(checkLoaded, 50);
			}
		};
		checkLoaded();

		return unsubscribe;
	});
</script>

{#if isLoading}
	<div class="loading-indicator">正在加载中...</div>
{:else}
	<main>
		<slot />
	</main>
{/if}

<style>
	.loading-indicator {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 1.2rem;
		background: #fff;
	}
</style>

这种方法同时覆盖初始加载和页面间导航的加载状态,适合需要全局统一加载提示的场景。

内容的提问来源于stack exchange,提问作者Infire

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 19:27:26