Svelte 最新中文文档翻译(7)—— snippet 与 @render

前言

Svelte,一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1

Svelte 最新中文文档翻译(7)—— snippet 与 @render_第1张图片

Svelte 以其独特的编译时优化机制著称,具有轻量级高性能易上手等特性,非常适合构建轻量级 Web 项目,也是我做个人项目的首选技术栈。

目前 Svelte 基于 Svelte 5 发布了最新的官方文档,但却缺少对应的中文文档。为了帮助大家学习 Svelte,为爱发电翻译了官方文档。

我同时搭建了 Svelte 最新的中文文档站点:https://svelte.yayujs.com ,如果需要辅助学习,也可以入手我的小册《Svelte 开发指南》,语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!

虽说是翻译,但个人并不喜欢严格遵守原文,为了保证中文阅读流畅,会删减部分语句,对难懂的部分也会另做补充解释,希望能给大家带来一个好的中文学习体验。

欢迎围观我的“朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。

snippet

{#snippet name()}...{/snippet}
{#snippet name(param1, param2, paramN)}...{/snippet}

代码片段和 渲染标签 是在组件内部创建可复用标记块的一种方法。与其编写这样的重复代码...

{#each images as image}
    {#if image.href}
        
            
{image.caption}
{image.caption}
{:else}
{image.caption}
{image.caption}
{/if} {/each}

...你可以这样写:

{#snippet figure(image)}
    
{image.caption}
{image.caption}
{/snippet} {#each images as image} {#if image.href} {@render figure(image)} {:else} {@render figure(image)} {/if} {/each}

像函数声明一样,代码片段可以有任意数量的参数,这些参数可以有默认值,并且你可以对每个参数进行解构。然而,你不能使用剩余参数。

代码片段作用域

代码片段可以在组件的任何地方声明。它们可以引用在自身之外声明的值,例如在 {#snippet hello(name)}

你好 {name}! {message}!

{/snippet} {@render hello('alice')} {@render hello('bob')}

...并且它们对同一词法作用域中的所有内容都是"可见的"(即兄弟节点和这些兄弟节点的子节点):

{#snippet x()} {#snippet y()}...{/snippet} {@render y()} {/snippet} {@render y()}
{@render x()}

代码片段可以引用自身和其他片段 (demo):

{#snippet blastoff()}
    
{/snippet}

{#snippet countdown(n)}
    {#if n > 0}
        {n}...
        {@render countdown(n - 1)}
    {:else}
        {@render blastoff()}
    {/if}
{/snippet}

{@render countdown(10)}

将代码片段传递给组件

在模板中,代码片段和其他值一样。这样,它们可以作为 props 传递给组件 (demo):



{#snippet header()}
    水果
    数量
    价格
    总计
{/snippet}

{#snippet row(d)}
    {d.name}
    {d.qty}
    {d.price}
    {d.qty * d.price}
{/snippet}

把它想象成向组件传递内容而非数据。这个概念类似于 Web 组件中的插槽。

为了方便,直接在组件内部声明的代码片段会隐式成为组件的 props (demo):


{#snippet header()} {/snippet} {#snippet row(d)} {/snippet}
水果 数量 价格 总计{d.name} {d.qty} {d.price} {d.qty * d.price}

组件标签内的任何不是代码片段声明的内容都将隐式成为 children 代码片段的一部分 (demo):






[!NOTE] 请注意,如果组件内部还有内容,你不能有名为 children 的 prop — 基于这个原因,应该避免使用这个名称作为 prop

你可以将代码片段 props 声明为可选的。你可以使用可选链,当代码片段未设置时不渲染任何内容...



{@render children?.()}

...或者使用 #if 块来渲染后备内容:



{#if children}
    {@render children()}
{:else}
    后备内容
{/if}

代码片段类型

代码片段实现了从 'svelte' 导入的 Snippet 接口:

通过这项改动,如果你尝试在没有提供 data prop 和 row 代码片段的情况下使用该组件,则会出现红色波浪线。请注意,提供给 Snippet 的类型参数是一个元组,因为代码片段可以有多个参数。

我们可以通过声明泛型来进一步收窄类型,以便 datarow 引用相同的类型:

导出代码片段

.svelte 文件顶层声明的代码片段可以从 {#snippet add(a, b)} {a} + {b} = {a + b} {/snippet}

[!NOTE]
这需要 Svelte 5.5.0 或更新版本

程序化代码片段

代码片段可以通过 createRawSnippet API 以编程方式创建。这适用于高级用例。

代码片段和插槽

在 Svelte 4 中,可以使用 插槽 将内容传递给组件。代码片段更强大、更灵活,因此在 Svelte 5 中插槽已被弃用。

{@render ...}

要渲染一个代码片段,请使用 {@render ...} 标签。

{#snippet sum(a, b)}
    

{a} + {b} = {a + b}

{/snippet} {@render sum(1, 2)} {@render sum(3, 4)} {@render sum(5, 6)}

表达式可以是像 sum 这样的标识符,也可以是任意的 JavaScript 表达式:

{@render (cool ? coolSnippet : lameSnippet)()}

可选代码片段

如果代码片段可能未定义 — 例如,因为它是一个传入的 prop — 那么你可以使用可选链操作符,只在代码片段确实存在时才渲染它:

{@render children?.()}

或者,使用{#if ...} 块配合 :else 子句来渲染后备内容:

{#if children}
    {@render children()}
{:else}
    

后备内容

{/if}

你可能感兴趣的:(Svelte 最新中文文档翻译(7)—— snippet 与 @render)