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
相关产品推荐
相关产品推荐

