We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Svelte,一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:
Svelte 以其独特的编译时优化机制著称,具有轻量级、高性能、易上手等特性,非常适合构建轻量级 Web 项目,也是我做个人项目的首选技术栈。
目前 Svelte 基于 Svelte 5 发布了最新的官方文档,但却缺少对应的中文文档。为了帮助大家学习 Svelte,为爱发电翻译了官方文档。
我同时搭建了 Svelte 最新的中文文档站点:https://svelte.yayujs.com ,如果需要辅助学习,也可以入手我的小册《Svelte 开发指南》,语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!
虽说是翻译,但个人并不喜欢严格遵守原文,为了保证中文阅读流畅,会删减部分语句,对难懂的部分也会另做补充解释,希望能给大家带来一个好的中文学习体验。
欢迎围观我的“朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。
{#snippet name()}...{/snippet}
{#snippet name(param1, param2, paramN)}...{/snippet}
代码片段和 渲染标签 是在组件内部创建可复用标记块的一种方法。与其编写这样的重复代码...
{#each images as image} {#if image.href} <a href={image.href}> <figure> <img src={image.src} alt={image.caption} width={image.width} height={image.height} /> <figcaption>{image.caption}</figcaption> </figure> </a> {:else} <figure> <img src={image.src} alt={image.caption} width={image.width} height={image.height} /> <figcaption>{image.caption}</figcaption> </figure> {/if} {/each}
...你可以这样写:
{#snippet figure(image)} <figure> <img src={image.src} alt={image.caption} width={image.width} height={image.height} /> <figcaption>{image.caption}</figcaption> </figure> {/snippet} {#each images as image} {#if image.href} <a href={image.href}> {@render figure(image)} </a> {:else} {@render figure(image)} {/if} {/each}
像函数声明一样,代码片段可以有任意数量的参数,这些参数可以有默认值,并且你可以对每个参数进行解构。然而,你不能使用剩余参数。
代码片段可以在组件的任何地方声明。它们可以引用在自身之外声明的值,例如在 <script> 标签或 {#each ...} 块中 (demo)...
<script>
{#each ...}
<script> let { message = `很高兴见到你!` } = $props(); </script> {#snippet hello(name)} <p>你好 {name}! {message}!</p> {/snippet} {@render hello('alice')} {@render hello('bob')}
...并且它们对同一词法作用域中的所有内容都是"可见的"(即兄弟节点和这些兄弟节点的子节点):
<div> {#snippet x()} {#snippet y()}...{/snippet} <!-- 这很好 --> {@render y()} {/snippet} <!-- 这将出错,因为 `y` 不在作用域中 --> {@render y()} </div> <!-- 这也将出错,因为 `x` 不在作用域中 --> {@render x()}
代码片段可以引用自身和其他片段 (demo):
{#snippet blastoff()} <span>🚀</span> {/snippet} {#snippet countdown(n)} {#if n > 0} <span>{n}...</span> {@render countdown(n - 1)} {:else} {@render blastoff()} {/if} {/snippet} {@render countdown(10)}
在模板中,代码片段和其他值一样。这样,它们可以作为 props 传递给组件 (demo):
<script> import Table from './Table.svelte'; const fruits = [ { name: '苹果', qty: 5, price: 2 }, { name: '香蕉', qty: 10, price: 1 }, { name: '樱桃', qty: 20, price: 0.5 } ]; </script> {#snippet header()} <th>水果</th> <th>数量</th> <th>价格</th> <th>总计</th> {/snippet} {#snippet row(d)} <td>{d.name}</td> <td>{d.qty}</td> <td>{d.price}</td> <td>{d.qty * d.price}</td> {/snippet} <Table data={fruits} {header} {row} />
把它想象成向组件传递内容而非数据。这个概念类似于 Web 组件中的插槽。
为了方便,直接在组件内部声明的代码片段会隐式成为组件的 props (demo):
<!-- 这在语义上与上面的相同 --> <Table data={fruits}> {#snippet header()} <th>水果</th> <th>数量</th> <th>价格</th> <th>总计</th> {/snippet} {#snippet row(d)} <td>{d.name}</td> <td>{d.qty}</td> <td>{d.price}</td> <td>{d.qty * d.price}</td> {/snippet} </Table>
组件标签内的任何不是代码片段声明的内容都将隐式成为 children 代码片段的一部分 (demo):
children
<!--- file: App.svelte ---> <Button>点击我</Button>
<!--- file: Button.svelte ---> <script> let { children } = $props(); </script> <!-- 结果将是 <button>点击我</button> --> <button>{@render children()}</button>
[!NOTE] 请注意,如果组件内部还有内容,你不能有名为 children 的 prop — 基于这个原因,应该避免使用这个名称作为 prop
你可以将代码片段 props 声明为可选的。你可以使用可选链,当代码片段未设置时不渲染任何内容...
<script> let { children } = $props(); </script> {@render children?.()}
...或者使用 #if 块来渲染后备内容:
#if
<script> let { children } = $props(); </script> {#if children} {@render children()} {:else} 后备内容 {/if}
代码片段实现了从 'svelte' 导入的 Snippet 接口:
'svelte'
Snippet
<script lang="ts"> import type { Snippet } from 'svelte'; interface Props { data: any[]; children: Snippet; row: Snippet<[any]>; } let { data, children, row }: Props = $props(); </script>
通过这项改动,如果你尝试在没有提供 data prop 和 row 代码片段的情况下使用该组件,则会出现红色波浪线。请注意,提供给 Snippet 的类型参数是一个元组,因为代码片段可以有多个参数。
data
row
我们可以通过声明泛型来进一步收窄类型,以便 data 和 row 引用相同的类型:
<script lang="ts" generics="T"> import type { Snippet } from 'svelte'; let { data, children, row }: { data: T[]; children: Snippet; row: Snippet<[T]>; } = $props(); </script>
在 .svelte 文件顶层声明的代码片段可以从 <script module> 导出以供其他组件使用,前提是它们不引用非模块 <script> 中的任何声明(无论是直接引用还是通过其他代码片段间接引用) (demo):
.svelte
<script module>
<script module> export { add }; </script> {#snippet add(a, b)} {a} + {b} = {a + b} {/snippet}
Note
这需要 Svelte 5.5.0 或更新版本
代码片段可以通过 createRawSnippet API 以编程方式创建。这适用于高级用例。
createRawSnippet
在 Svelte 4 中,可以使用 插槽 将内容传递给组件。代码片段更强大、更灵活,因此在 Svelte 5 中插槽已被弃用。
要渲染一个代码片段,请使用 {@render ...} 标签。
{@render ...}
{#snippet sum(a, b)} <p>{a} + {b} = {a + b}</p> {/snippet} {@render sum(1, 2)} {@render sum(3, 4)} {@render sum(5, 6)}
表达式可以是像 sum 这样的标识符,也可以是任意的 JavaScript 表达式:
sum
{@render (cool ? coolSnippet : lameSnippet)()}
如果代码片段可能未定义 — 例如,因为它是一个传入的 prop — 那么你可以使用可选链操作符,只在代码片段确实存在时才渲染它:
{@render children?.()}
或者,使用{#if ...} 块配合 :else 子句来渲染后备内容:
{#if ...}
:else
{#if children} {@render children()} {:else} <p>后备内容</p> {/if}
本篇已收录在掘金专栏 《Svelte 中文文档》,该系列预计 40 篇。
系统学习 Svelte,欢迎入手小册《Svelte 开发指南》。语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!
此外我还写过 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、冴羽答读者问等 14 个系列文章, 全系列文章目录:https://github.com/mqyqingfeng/Blog
通过文字建立交流本身就是一种缘分,欢迎围观我的“朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
Svelte,一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:
Svelte 以其独特的编译时优化机制著称,具有轻量级、高性能、易上手等特性,非常适合构建轻量级 Web 项目,也是我做个人项目的首选技术栈。
目前 Svelte 基于 Svelte 5 发布了最新的官方文档,但却缺少对应的中文文档。为了帮助大家学习 Svelte,为爱发电翻译了官方文档。
我同时搭建了 Svelte 最新的中文文档站点:https://svelte.yayujs.com ,如果需要辅助学习,也可以入手我的小册《Svelte 开发指南》,语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!
虽说是翻译,但个人并不喜欢严格遵守原文,为了保证中文阅读流畅,会删减部分语句,对难懂的部分也会另做补充解释,希望能给大家带来一个好的中文学习体验。
欢迎围观我的“朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。
snippet
代码片段和 渲染标签 是在组件内部创建可复用标记块的一种方法。与其编写这样的重复代码...
...你可以这样写:
像函数声明一样,代码片段可以有任意数量的参数,这些参数可以有默认值,并且你可以对每个参数进行解构。然而,你不能使用剩余参数。
代码片段作用域
代码片段可以在组件的任何地方声明。它们可以引用在自身之外声明的值,例如在
<script>
标签或{#each ...}
块中 (demo)......并且它们对同一词法作用域中的所有内容都是"可见的"(即兄弟节点和这些兄弟节点的子节点):
代码片段可以引用自身和其他片段 (demo):
将代码片段传递给组件
在模板中,代码片段和其他值一样。这样,它们可以作为 props 传递给组件 (demo):
把它想象成向组件传递内容而非数据。这个概念类似于 Web 组件中的插槽。
为了方便,直接在组件内部声明的代码片段会隐式成为组件的 props (demo):
组件标签内的任何不是代码片段声明的内容都将隐式成为
children
代码片段的一部分 (demo):你可以将代码片段 props 声明为可选的。你可以使用可选链,当代码片段未设置时不渲染任何内容...
...或者使用
#if
块来渲染后备内容:代码片段类型
代码片段实现了从
'svelte'
导入的Snippet
接口:通过这项改动,如果你尝试在没有提供
data
prop 和row
代码片段的情况下使用该组件,则会出现红色波浪线。请注意,提供给Snippet
的类型参数是一个元组,因为代码片段可以有多个参数。我们可以通过声明泛型来进一步收窄类型,以便
data
和row
引用相同的类型:导出代码片段
在
.svelte
文件顶层声明的代码片段可以从<script module>
导出以供其他组件使用,前提是它们不引用非模块<script>
中的任何声明(无论是直接引用还是通过其他代码片段间接引用) (demo):Note
这需要 Svelte 5.5.0 或更新版本
程序化代码片段
代码片段可以通过
createRawSnippet
API 以编程方式创建。这适用于高级用例。代码片段和插槽
在 Svelte 4 中,可以使用 插槽 将内容传递给组件。代码片段更强大、更灵活,因此在 Svelte 5 中插槽已被弃用。
{@render ...}
要渲染一个代码片段,请使用
{@render ...}
标签。表达式可以是像
sum
这样的标识符,也可以是任意的 JavaScript 表达式:可选代码片段
如果代码片段可能未定义 — 例如,因为它是一个传入的 prop — 那么你可以使用可选链操作符,只在代码片段确实存在时才渲染它:
或者,使用
{#if ...}
块配合:else
子句来渲染后备内容:Svelte 中文文档
本篇已收录在掘金专栏 《Svelte 中文文档》,该系列预计 40 篇。
系统学习 Svelte,欢迎入手小册《Svelte 开发指南》。语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!
此外我还写过 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、冴羽答读者问等 14 个系列文章, 全系列文章目录:https://github.com/mqyqingfeng/Blog
通过文字建立交流本身就是一种缘分,欢迎围观我的“朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。
The text was updated successfully, but these errors were encountered: