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

Svelte多组件复用REST API数据及轮询方案咨询

Svelte中API数据复用与轮询方案

一、仅调用一次API实现多组件数据复用

1. 页面组件内获取数据并通过Props传递

在根页面(+page.svelte)中统一调用API,将获取到的数据通过props传递给所有子组件:

<!-- +page.svelte -->
<script>
  let todos = [];
  let isLoading = true;

  async function fetchTodos() {
    const response = await fetch('https://jsonplaceholder.typicode.com/todos/');
    todos = await response.json();
    isLoading = false;
  }

  // 页面加载时调用一次
  fetchTodos();
</script>

<div class="page-content">
  {#if isLoading}
    <p>加载中...</p>
  {:else}
    <Row>
      <Table1 {todos} />
      <List {todos} />
      <Table2 {todos} />
    </Row>
  {/if}
</div>

子组件接收props并使用:

<!-- Table1.svelte -->
<script>
  export let todos;
</script>

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>标题</th>
    </tr>
  </thead>
  <tbody>
    {#each todos as todo}
      <tr>
        <td>{todo.id}</td>
        <td>{todo.title}</td>
      </tr>
    {/each}
  </tbody>
</table>

2. 使用Svelte Store全局共享数据

创建全局状态存储,所有组件订阅该存储实现数据复用,仅需初始化时调用一次API:

// src/lib/stores/todos.js
import { writable } from 'svelte/store';

export const todosStore = writable([]);

export async function fetchAndUpdateTodos() {
  const response = await fetch('https://jsonplaceholder.typicode.com/todos/');
  const data = await response.json();
  todosStore.set(data);
}

页面组件初始化数据:

<!-- +page.svelte -->
<script>
  import { fetchAndUpdateTodos } from '$lib/stores/todos';

  // 页面加载时调用一次
  fetchAndUpdateTodos();
</script>

<div class="page-content">
  <Row>
    <Table1 />
    <List />
    <Table2 />
  </Row>
</div>

子组件订阅store使用数据:

<!-- Table1.svelte -->
<script>
  import { todosStore } from '$lib/stores/todos';
</script>

{#each $todosStore as todo}
  <!-- 渲染表格内容 -->
{/each}

3. 使用SvelteKit的Page Load函数预取数据

SvelteKit项目中,通过+page.js的load函数在页面加载前获取数据,自动传递给页面组件:

// +page.js
export async function load() {
  const response = await fetch('https://jsonplaceholder.typicode.com/todos/');
  const todos = await response.json();
  return { todos };
}

页面组件接收数据并传递给子组件:

<!-- +page.svelte -->
<script>
  export let data;
  const { todos } = data;
</script>

<div class="page-content">
  <Row>
    <Table1 {todos} />
    <List {todos} />
    <Table2 {todos} />
  </Row>
</div>

二、15秒轮询API的优化方案

轮询需保证全局仅触发一次请求,所有组件共享更新后的数据,以下是可行方案:

1. 基于Store的定时轮询

在store中统一管理轮询逻辑,避免多组件重复触发:

// src/lib/stores/todos.js
import { writable } from 'svelte/store';

export const todosStore = writable([]);
let pollInterval;

export async function fetchAndUpdateTodos() {
  const response = await fetch('https://jsonplaceholder.typicode.com/todos/');
  const data = await response.json();
  todosStore.set(data);
}

export function startPolling(interval = 15000) {
  // 先调用一次获取初始数据
  fetchAndUpdateTodos();
  // 设置定时轮询
  pollInterval = setInterval(fetchAndUpdateTodos, interval);
}

export function stopPolling() {
  if (pollInterval) clearInterval(pollInterval);
}

页面组件中启动和停止轮询:

<!-- +page.svelte -->
<script>
  import { startPolling, stopPolling } from '$lib/stores/todos';
  import { onDestroy } from 'svelte';

  startPolling();

  // 页面销毁时停止轮询,避免内存泄漏
  onDestroy(stopPolling);
</script>

2. 页面组件内的定时轮询(Props传递场景)

若使用props传递数据,在页面组件中管理定时器,更新数据后自动同步给子组件:

<!-- +page.svelte -->
<script>
  import { onDestroy } from 'svelte';
  let todos = [];
  let pollInterval;

  async function fetchTodos() {
    const response = await fetch('https://jsonplaceholder.typicode.com/todos/');
    todos = await response.json();
  }

  function startPolling() {
    fetchTodos();
    pollInterval = setInterval(fetchTodos, 15000);
  }

  startPolling();

  onDestroy(() => {
    if (pollInterval) clearInterval(pollInterval);
  });
</script>

<!-- 子组件通过props接收todos -->

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 04:20:32