<slot>

  1. <slot><!-- 可选的后备内容 --></slot>
  1. <slot name="x"><!-- 可选的后备内容 --></slot>
  1. <slot prop={value} />

组件可以像元素一样拥有子内容。

内容在使用 <slot> 元素的子组件中暴露,如果未提供子内容,将呈现后备内容。

  1. <!-- Widget.svelte -->
  2. <div>
  3. <slot>
  4. 当未提供内容时,将呈现此后备内容,如第一个示例
  5. </slot>
  6. </div>
  7. <!-- App.svelte -->
  8. <Widget />
  9. <!-- 此组件将呈现默认内容 -->
  10. <Widget>
  11. <p>这是一些将覆盖默认插槽内容的子内容</p>
  12. </Widget>

注意:如果您想呈现常规的 <slot> 元素,您可以使用 <svelte:element this="slot" />

<slot name="_name_">

命名插槽允许使用者定位特定区域。它们也可以有后备内容。

  1. <!-- Widget.svelte -->
  2. <div>
  3. <slot name="header">未提供标题</slot>
  4. <p>标题和页脚之间的一些内容</p>
  5. <slot name="footer" />
  6. </div>
  7. <!-- App.svelte -->
  8. <Widget>
  9. <h1 slot="header">你好</h1>
  10. <p slot="footer">版权所有 (c) 2019 Svelte Industries</p>
  11. </Widget>

可以使用 <Component slot="name" /> 语法将组件放置在命名插槽中。为了在不使用包装元素的情况下将内容放入插槽,您可以使用特殊元素 <svelte:fragment>

  1. <!-- Widget.svelte -->
  2. <div>
  3. <slot name="header">未提供标题</slot>
  4. <p>标题和页脚之间的一些内容</p>
  5. <slot name="footer" />
  6. </div>
  7. <!-- App.svelte -->
  8. <Widget>
  9. <HeaderComponent slot="header" />
  10. <svelte:fragment slot="footer">
  11. <p>版权所有。</p>
  12. <p>版权所有 (c) 2019 Svelte Industries</p>
  13. </svelte:fragment>
  14. </Widget>

$$slots

slotsslots 是一个对象,其键是由父组件传递给组件的插槽名称。如果父组件没有传递具有特定名称的插槽,则该名称将不在 slots 中。这允许组件仅在父组件提供时才呈现插槽(和其他元素,如用于样式的包装器)。

请注意,显式传递一个空的命名插槽将添加该插槽的名称到 slotsslots。例如,如果父组件传递 <div slot="title" /> 到子组件,子组件内的 slots.title 将为真值。

  1. <!-- Card.svelte -->
  2. <div>
  3. <slot name="title" />
  4. {#if $$slots.description}
  5. <!-- 如果提供了名为 "description" 的插槽,则仅呈现此 <hr> 和插槽。 -->
  6. <hr />
  7. <slot name="description" />
  8. {/if}
  9. </div>
  10. <!-- App.svelte -->
  11. <Card>
  12. <h1 slot="title">博客文章标题</h1>
  13. <!-- 未提供名为 "description" 的插槽,因此可选插槽将不会呈现。 -->
  14. </Card>

<slot key={_value_}>

插槽可以呈现零次或多次,并且可以通过属性将值 回传 给父组件。父组件使用 let: 指令将值暴露给插槽模板。

通常的简写规则适用 —— let:item 等同于 let:item={item},并且 <slot {item}> 等同于 <slot item={item}>

  1. <!-- FancyList.svelte -->
  2. <ul>
  3. {#each items as item}
  4. <li class="fancy">
  5. <slot prop={item} />
  6. </li>
  7. {/each}
  8. </ul>
  9. <!-- App.svelte -->
  10. <FancyList {items} let:prop={thing}>
  11. <div>{thing.text}</div>
  12. </FancyList>

命名插槽也可以暴露值。let: 指令在具有 slot 属性的元素上。

  1. <!-- FancyList.svelte -->
  2. <ul>
  3. {#each items as item}
  4. <li class="fancy">
  5. <slot name="item" {item} />
  6. </li>
  7. {/each}
  8. </ul>
  9. <slot name="footer" />
  10. <!-- App.svelte -->
  11. <FancyList {items}>
  12. <div slot="item" let:item>{item.text}</div>
  13. <p slot="footer">版权所有 (c) 2019 Svelte Industries</p>
  14. </FancyList>

<svelte:self>

<svelte:self> 元素允许组件递归地包含自己。

它不能出现在标记的顶层;它必须在 if 或 each 块内,或者传递到组件的插槽中,以防止无限循环。

App.svelte

  1. <script>
  2. /** @type {number} */
  3. export let count;
  4. </script>
  5. {#if count > 0}
  6. <p>倒计时... {count}</p>
  7. <svelte:self count={count - 1} />
  8. {:else}
  9. <p>起飞!</p>
  10. {/if}

App.svelte

  1. <script lang="ts">
  2. export let count: number;
  3. </script>
  4. {#if count > 0}
  5. <p>倒计时... {count}</p>
  6. <svelte:self count={count - 1} />
  7. {:else}
  8. <p>起飞!</p>
  9. {/if}

<svelte:component>

  1. <svelte:component this={expression} />

<svelte:component> 元素使用 this 属性指定的组件构造函数动态呈现组件。当属性更改时,组件将被销毁并重新创建。

如果 this 是假值,则不呈现任何组件。

  1. <svelte:component this={currentSelection.component} foo={bar} />

<svelte:element>

  1. <svelte:element this={expression} />

<svelte:element> 元素允许您渲染动态指定类型的元素。这在例如从 CMS 显示富文本内容时非常有用。任何属性和事件侦听器都将应用于该元素。

唯一支持的绑定是 bind:this,因为 Svelte 在构建时对特定元素类型的绑定(例如,输入元素的 bind:value)不适用于动态标签类型。

如果 this 有一个空值,元素及其子元素将不会被渲染。

如果 this 是一个 空元素 的名称(例如 br),并且 <svelte:element> 有子元素,在开发模式下将抛出运行时错误。

  1. <script>
  2. let tag = 'div';
  3. export let handler;
  4. </script>
  5. <svelte:element this={tag} on:click={handler}>Foo</svelte:element>

<svelte:window>

  1. <svelte:window on:event={handler} />
  1. <svelte:window bind:prop={value} />

<svelte:window> 元素允许您向 window 对象添加事件侦听器,而不必担心在组件销毁时移除它们,或者在服务器端渲染时检查 window 的存在。

<svelte:self> 不同,此元素只能出现在组件的顶层,并且绝不能在块或元素内部。

App.svelte

  1. <script>
  2. /** @param {KeyboardEvent} event */
  3. function handleKeydown(event) {
  4. alert(`按下了 ${event.key} 键`);
  5. }
  6. </script>
  7. <svelte:window on:keydown={handleKeydown} />

App.svelte

  1. <script lang="ts">
  2. function handleKeydown(event: KeyboardEvent) {
  3. alert(`按下了 ${event.key} 键`);
  4. }
  5. </script>
  6. <svelte:window on:keydown={handleKeydown} />

您还可以绑定到以下属性:

  • innerWidth
  • innerHeight
  • outerWidth
  • outerHeight
  • scrollX
  • scrollY
  • onlinewindow.navigator.onLine 的别名
  • devicePixelRatio

除了 scrollXscrollY 之外,其余都是只读的。

  1. <svelte:window bind:scrollY={y} />

注意,为了避免可访问性问题,页面不会滚动到初始值。只有绑定到 scrollXscrollY 的变量的后续更改才会导致滚动。然而,如果需要滚动行为,请在 onMount() 中调用 scrollTo()

<svelte:document>

  1. <svelte
  2. :document on:event={handler} />
  1. <svelte:document bind:prop={value} />

<svelte:window> 类似,此元素允许您向 document 添加侦听器,例如 visibilitychange,这些事件不会在 window 上触发。它还允许您在 document 上使用 动作

<svelte:window> 一样,此元素只能出现在组件的顶层,并且绝不能在块或元素内部。

  1. <svelte:document on:visibilitychange={handleVisibilityChange} use:someAction />

您还可以绑定到以下属性:

  • fullscreenElement
  • visibilityState

全部都是只读的。

<svelte:body>

  1. <svelte:body on:event={handler} />

<svelte:window> 类似,此元素允许您向 document.body 添加侦听器,例如 mouseentermouseleave,这些事件不会在 window 上触发。它还允许您在 <body> 元素上使用 动作

<svelte:window><svelte:document> 一样,此元素只能出现在组件的顶层,并且绝不能在块或元素内部。

  1. <svelte:body on:mouseenter={handleMouseenter} on:mouseleave={handleMouseleave} use:someAction />

<svelte:head>

  1. <svelte:head>...</svelte:head>

此元素使您可以将元素插入 document.head。在服务器端渲染期间,head 内容与主要 html 内容分开暴露。

<svelte:window><svelte:document><svelte:body> 一样,此元素只能出现在组件的顶层,并且绝不能在块或元素内部。

  1. <svelte:head>
  2. <title>你好,世界!</title>
  3. <meta name="description" content="这是 SEO 的描述位置" />
  4. </svelte:head>

<svelte:options>

  1. <svelte:options option={value} />

<svelte:options> 元素提供了一个指定每个组件的编译器选项的地方,这些选项在 编译器部分 中详细说明。可能的选项有:

  • immutable={true} — 您从不使用可变数据,因此编译器可以进行简单的引用等值检查以确定值是否已更改
  • immutable={false} — 默认值。Svelte 将更加保守地判断可变对象是否已更改
  • accessors={true} — 为组件的属性添加 getter 和 setter
  • accessors={false} — 默认值
  • namespace="..." — 此组件将使用的命名空间,最常见的是 “svg”;使用 “foreign” 命名空间来选择退出不区分大小写的属性名称和 HTML 特定警告
  • customElement="..." — 编译此组件为自定义元素时使用的名称
  1. <svelte:options customElement="my-custom-element" />

<svelte:fragment>

<svelte:fragment> 元素允许您在 命名插槽 中放置内容,而不需要用容器 DOM 元素包装它。这保持了文档的流程布局的完整性。

  1. <!-- Widget.svelte -->
  2. <div>
  3. <slot name="header">未提供标题</slot>
  4. <p>标题和页脚之间的一些内容</p>
  5. <slot name="footer" />
  6. </div>
  7. <!-- App.svelte -->
  8. <Widget>
  9. <h1 slot="header">你好</h1>
  10. <svelte:fragment slot="footer">
  11. <p>版权所有。</p>
  12. <p>版权所有 (c) 2019 Svelte Industries</p>
  13. </svelte:fragment>
  14. </Widget>