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

Svelte 5/SvelteKit 2中动态导入SVG加密货币图标失效求助

问题:SvelteKit 2中动态导入加密货币SVG图标无法渲染

我正在使用Svelte 5/SvelteKit 2,从API获取的数据格式如下:

const itemsFromAPI = [
    { id: 1, symbols: ['btc', 'eth'] },
    { id: 2, symbols: ['xrp', 'xmr'] }
];

我希望通过加密货币图标库渲染每个符号对应的SVG图标(已知该库有Svelte版本但已5年未更新,因此不打算使用)。我编写了+page.svelte文件,但图标无法渲染,代码如下:

<script>
    const itemsFromAPI = [
        { id: 1, symbols: ['btc', 'eth'] },
        { id: 2, symbols: ['xrp', 'xmr'] }
    ];

    const handleIconChange = async (iconName) => {
        return await import(`/node_modules/cryptocurrency-icons/svg/color/${iconName}.svg?inline`);
    };
</script>

<h1>How to make dynamic crypto icons work here</h1>

{#each itemsFromAPI as item (item.id)}
    <div>
        <span>{item.id}</span>
        {#each item.symbols as symbol (symbol)}
            <span>{symbol}</span>
            <span>{@html handleIconChange(symbol)}</span>
        {/each}
    </div>
{/each}

解决方案

你的代码存在两个核心问题,以下是针对性的修正方案:

1. 修正动态导入逻辑与渲染方式

SvelteKit中,?inline导入SVG返回的是Svelte组件模块,而非直接可用的HTML字符串;且异步函数无法直接在{@html}中调用,必须配合{#await}块处理异步结果。推荐使用?raw后缀直接获取SVG文本内容,再通过{@html}渲染:

修正后的基础版本代码

<script>
    const itemsFromAPI = [
        { id: 1, symbols: ['btc', 'eth'] },
        { id: 2, symbols: ['xrp', 'xmr'] }
    ];

    async function getSvgContent(symbol) {
        try {
            // 省略/node_modules/前缀,SvelteKit会自动从依赖中查找
            const module = await import(`cryptocurrency-icons/svg/color/${symbol}.svg?raw`);
            return module.default;
        } catch (err) {
            console.error(`加载图标 ${symbol} 失败:`, err);
            return '';
        }
    }
</script>

<h1>动态加密货币图标渲染示例</h1>

{#each itemsFromAPI as item (item.id)}
    <div>
        <span>{item.id}</span>
        {#each item.symbols as symbol (symbol)}
            <span>{symbol}</span>
            <!-- 用{#await}处理异步获取的SVG内容 -->
            {#await getSvgContent(symbol)}
                <span>加载中...</span>
            {:then svgContent}
                <span>{@html svgContent}</span>
            {:catch}
                <span>图标加载失败</span>
            {/await}
        {/each}
    </div>
{/each}

2. 优化方案:预加载图标减少异步请求

如果API返回的符号数量不多或可提前预知,可以预加载所有需要的图标,避免多次异步请求:

<script>
    const itemsFromAPI = [
        { id: 1, symbols: ['btc', 'eth'] },
        { id: 2, symbols: ['xrp', 'xmr'] }
    ];

    // 缓存已加载的SVG内容
    const svgCache = {};

    // 页面初始化时预加载所有需要的图标
    async function preloadIcons() {
        const allSymbols = itemsFromAPI.flatMap(item => item.symbols);
        for (const symbol of allSymbols) {
            if (!svgCache[symbol]) {
                const module = await import(`cryptocurrency-icons/svg/color/${symbol}.svg?raw`);
                svgCache[symbol] = module.default;
            }
        }
    }

    preloadIcons();
</script>

<h1>预加载加密货币图标示例</h1>

{#each itemsFromAPI as item (item.id)}
    <div>
        <span>{item.id}</span>
        {#each item.symbols as symbol (symbol)}
            <span>{symbol}</span>
            {#if svgCache[symbol]}
                <span>{@html svgCache[symbol]}</span>
            {:else}
                <span>加载中...</span>
            {/if}
        {/each}
    </div>
{/each}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 22:02:42