如何在Svelte中渲染一个带有预定义属性值的代码片段?

前端开发 2026-07-08

如果我有一个Svelte文件,里面有两个片段,一个类型为 Snippet<[]>,另一个为 Snippet<[string]>,我想用一个预定义的状态变量动态渲染后者。

Here is a reproducible example that can be directly placed in [Svelte playground]:

<script lang="ts">
    let useNoParamSnippet: boolean = $state(true);

    let textToUseInStringParamSnippet: string = $state("Hello");

    let snippetToRender = $derived(
        useNoParamSnippet 
            ? noParamSnippet
            : () => stringParamSnippet(textToUseInStringParamSnippet)
    );
</script>

{#snippet noParamSnippet()}
    <p>No parameter snippet.</p>
{/snippet}

{#snippet stringParamSnippet(text: string)}
    <p>Snippet with parameter: {text}</p>
{/snippet}

<button onclick={() => useNoParamSnippet = !useNoParamSnippet}>
    Use other snippet
</button>


{@render snippetToRender()}

{@render stringParamSnippet("This is another, non-dynamic instance of that same snippet.")}

尝试以这种方式渲染 stringParamSnippet 时,出现的错误是:

未捕获的Svelte错误:invalid_snippet_arguments。
一个片段函数被传递了无效参数。片段应该仅通过 {@render ...} 实例化。
https://svelte.dev/e/invalid_snippet_arguments

I don't want to use the variable directly in the snippet and convert it to a no-parameter snippet, as I use the same snippet directly in another place in the template as well.

这样做可行吗?

解决方案

这是可行的,但你将不得不越过内部边界,这可能随时导致问题。有一个长期存在的 issue,倡导为此添加一种被广泛认可的实现方式。

这个变通做法看起来是这样的:

let snippetToRender = $derived(
    useNoParamSnippet 
        ? noParamSnippet
        : $anchor => stringParamSnippet(
            $anchor,
            () => textToUseInStringParamSnippet,
          )
);

演练环境

#snippet 生成的函数的第一个参数就是插入点节点。
并且参数必须以函数的形式传递,这样才能保持响应性。

(服务器端渲染的签名不同。)

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章