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

Svelte实现多按钮触发Fetch请求(取消初始自动请求)

Svelte多按钮按需请求数据实现方案

原代码问题分析

你当前的fetch.js中,fetchStore函数在创建后会自动调用内部的get()方法,导致页面加载时就发起请求。要实现点击对应按钮才触发请求,需要去掉自动调用逻辑,并让请求触发逻辑由按钮点击事件控制。

核心修改原理

  1. 移除fetchStore内部的自动get()调用,让请求仅在外部主动调用时触发。
  2. 让get()方法支持动态传入URL,适配不同按钮的请求目标。
  3. 可选择使用共享状态或独立状态:共享状态适合所有按钮复用同一展示区域,独立状态适合每个按钮对应单独的结果展示。

实现方案

方案1:共享状态(所有按钮共用同一结果区域)

修改fetch.js

import { writable } from 'svelte/store'

export default function fetchStore(initialUrl = null) {
    const loading = writable(false)
    const error = writable(false)
    const data = writable({})
    let currentUrl = initialUrl

    async function get(url = currentUrl) {
        if (!url) return
        loading.set(true)
        error.set(false)
        try {
            const response = await fetch(url)
            if (!response.ok) throw new Error(`请求失败:${response.status}`)
            data.set(await response.json())
            currentUrl = url
        } catch(e) {
            error.set(e.message || e.toString())
        }
        loading.set(false)
    }

    // 移除自动调用get(),改为外部触发
    return [ data, loading, error, get ]
}

修改App.Svelte

<script>
    import fetchStore from './fetch.js'
    // 创建一个共享的fetch状态实例
    const [data, loading, error, get] = fetchStore()

    // 定义按钮对应的请求配置
    const requestItems = [
        { label: '获取卢克数据', url: 'https://www.swapi.tech/api/people/1' },
        { label: '获取莱娅数据', url: 'https://www.swapi.tech/api/people/5' },
        { label: '获取维达数据', url: 'https://www.swapi.tech/api/people/4' }
    ]
</script>

<div class="button-container">
    {#each requestItems as item}
        <button on:click={() => get(item.url)}>
            {item.label}
        </button>
    {/each}
</div>

{#if $loading}
    <p>加载中...</p>
{:else if $error}
    <p style="color: #dc2626;">错误:{$error}</p>
{:else if Object.keys($data).length > 0}
    <pre>{JSON.stringify($data, null, 2)}</pre>
{:else}
    <p>点击上方按钮获取数据</p>
{/if}

<style>
    .button-container {
        gap: 0.5rem;
        display: flex;
        margin: 1rem 0;
    }
</style>

方案2:独立状态(每个按钮对应单独的结果区域)

如果需要每个按钮的加载、错误、数据状态独立展示,可为每个请求创建单独的fetchStore实例:

App.Svelte代码

<script>
    import fetchStore from './fetch.js'

    // 为每个请求创建独立的状态实例
    const requestItems = [
        { 
            label: '卢克', 
            url: 'https://www.swapi.tech/api/people/1',
            ...fetchStore()
        },
        { 
            label: '莱娅', 
            url: 'https://www.swapi.tech/api/people/5',
            ...fetchStore()
        },
        { 
            label: '维达', 
            url: 'https://www.swapi.tech/api/people/4',
            ...fetchStore()
        }
    ]
</script>

{#each requestItems as item}
    <div class="card">
        <button on:click={() => item.get(item.url)}>
            获取{item.label}数据
        </button>
        {#if $item.loading}
            <p>加载中...</p>
        {:else if $item.error}
            <p style="color: #dc2626;">错误:{$item.error}</p>
        {:else if Object.keys($item.data).length > 0}
            <pre>{JSON.stringify($item.data, null, 2)}</pre>
        {/if}
    </div>
{/each}

<style>
    .card {
        margin: 1rem 0;
        padding: 1rem;
        border: 1px solid #e5e7eb;
        border-radius: 6px;
    }
</style>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:15:43