如何在Svelte中渲染一个带有预定义属性值的代码片段?
如果我有一个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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。