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

Svelte从API获取数据后UI未渲染问题求助

问题分析

你的核心问题出在模板中的{#await}只会执行一次,而getData函数虽然依赖data,但它不是响应式的——当onMount中更新data后,不会重新触发getData执行,导致UI一直使用初始的空数组结果。另外,getData标记为async完全没必要,函数内部没有异步操作,反而让{#await}误以为它是异步任务,初始执行后就不再关注后续的data变化。

修复方案

方案1:直接在模板中处理数据(最简洁)

去掉getData函数,直接在模板里根据show_all和data的值渲染,利用Svelte的响应式自动更新UI:

<script lang="ts">
    import Card from "../../components/Card.svelte";
    import { onMount } from "svelte";

    let show_all = false;
    let data: Array<{id: number, image_url: string, description: string, link: string, title: string}> = [];
    let loading = true;
    let error: Error | null = null;

    onMount(async () => {
        try {
            const response = await fetch("http://localhost:4000/entries");
            data = await response.json();
        } catch(err) {
            error = err as Error;
        } finally {
            loading = false;
        }
    });
</script>

{#if loading}
    <p>...waiting</p>
{:else if error}
    <p style="color: red">{error.message}</p>
{:else}
    {#each (show_all ? data : data.slice(0, 12)) as item (item.id)}
        <Card 
            image_url={item.image_url} 
            description={item.description} 
            link={item.link}  
            title={item.title} 
        />
    {/each}
{/if}

方案2:使用响应式派生值封装逻辑

如果想把数据筛选逻辑封装起来,用Svelte的响应式声明($:)定义filteredData,这样当data或show_all变化时,它会自动重新计算:

<script lang="ts">
    import Card from "../../components/Card.svelte";
    import { onMount } from "svelte";

    let show_all = false;
    let data: Array<{id: number, image_url: string, description: string, link: string, title: string}> = [];
    let loading = true;
    let error: Error | null = null;

    onMount(async () => {
        try {
            const response = await fetch("http://localhost:4000/entries");
            data = await response.json();
        } catch(err) {
            error = err as Error;
        } finally {
            loading = false;
        }
    });

    // 响应式派生值,依赖data和show_all变化自动更新
    $: filteredData = show_all ? data : data.slice(0, 12);
</script>

{#if loading}
    <p>...waiting</p>
{:else if error}
    <p style="color: red">{error.message}</p>
{:else}
    {#each filteredData as item (item.id)}
        <Card 
            image_url={item.image_url} 
            description={item.description} 
            link={item.link}  
            title={item.title} 
        />
    {/each}
{/if}
关键知识点
  • Svelte的响应式基于变量赋值,当data被重新赋值后,所有依赖它的模板或响应式声明都会自动更新。
  • {#await}适合处理真正的异步Promise(比如直接的fetch请求),不适合同步响应式逻辑,因为它只会执行一次Promise解析过程。
  • 响应式声明($:)是Svelte处理派生数据的核心方式,依赖变量变化时,声明块会自动重新执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 20:50:23