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

SvelteKit技术问题:如何仅调用一次Fetch API而非每次路由切换都请求

解决方案

1. 使用SvelteKit的load函数(适用于SvelteKit项目)

如果项目基于SvelteKit,可将数据请求放在页面组件的load函数中。该函数仅在页面首次加载或路由参数变化时执行,同参数路由切换不会重复调用,数据会被SvelteKit自动缓存。

示例:

// +page.js
export async function load({ fetch }) {
  const response = await fetch(url);
  const poem = await response.json();
  return { poem };
}

页面组件中直接使用返回的数据:

<script>
  export let data;
</script>

{#if data.poem}
  <pre>{data.poem.plainText}</pre>
{:else}
  <b>Loading...</b>
{/if}

2. 全局状态管理(Svelte Store)

将请求到的数据存入全局状态(如Svelte的writable store),组件挂载时先检查store内是否已有数据,无数据时再发起请求。无论组件挂载多少次,只要store中有数据就不会重复请求。

示例:

// stores.js
import { writable, get } from 'svelte/store';

export const poemStore = writable(null);

export async function fetchPoem(url) {
  const existingData = get(poemStore);
  if (!existingData) {
    const response = await fetch(url);
    const poem = await response.json();
    poemStore.set(poem);
  }
}

组件中使用store:

<script>
  import { onMount, onDestroy } from "svelte";
  import { poemStore, fetchPoem } from './stores.js';

  let poem = null;
  const unsubscribe = poemStore.subscribe(value => {
    poem = value;
  });

  onMount(async () => {
    await fetchPoem(url);
  });

  onDestroy(() => {
    unsubscribe();
  });
</script>

{#if poem}
  <pre>{poem.plainText}</pre>
{:else}
  <b>Loading...</b>
{/if}

3. 组件缓存(Keep-Alive)

借助第三方库(如svelte-keep-alive)实现组件缓存,让路由切换时组件不被销毁,保持挂载状态,这样onMount只会执行一次。

示例(路由容器组件):

<script>
  import { KeepAlive } from 'svelte-keep-alive';
  import { page } from '$app/stores';
</script>

<KeepAlive>
  <svelte:component this={$page.component} {...$page.props} />
</KeepAlive>

4. 父组件统一请求并传参

将数据请求逻辑放在父组件(如布局组件)中,父组件仅请求一次数据,再通过props将数据传递给子组件。子组件直接接收props使用,无需自行请求。

示例:

<!-- 父组件(布局组件) -->
<script>
  import { onMount } from "svelte";
  import ChildComponent from './ChildComponent.svelte';

  let poem = null;

  onMount(async () => {
    const response = await fetch(url);
    poem = await response.json();
  });
</script>

{#if poem}
  <ChildComponent {poem} />
{:else}
  <b>Loading...</b>
{/if}
<!-- 子组件 -->
<script>
  export let poem;
</script>

<pre>{poem.plainText}</pre>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 17:05:18