跳至主要内容

模板语法

特殊元素

在 GitHub 上编辑此页面

<slot>

<slot><!-- optional fallback --></slot>
<slot name="x"><!-- optional fallback --></slot>
<slot prop={value} />

组件可以包含子内容,就像元素一样。

使用 <slot> 元素在子组件中显示内容,如果未提供子内容,该元素可以包含备用内容进行渲染。

<!-- Widget.svelte -->
<div>
	<slot>
		this fallback content will be rendered when no content is provided, like in the first example
	</slot>
</div>

<!-- App.svelte -->
<Widget />
<!-- this component will render the default content -->

<Widget>
	<p>this is some child content that will overwrite the default slot content</p>
</Widget>

注意:如果你想渲染常规 <slot> 元素,可以使用 <svelte:element this="slot" />

<slot name="name">

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

<!-- Widget.svelte -->
<div>
	<slot name="header">No header was provided</slot>
	<p>Some content between header and footer</p>
	<slot name="footer" />
</div>

<!-- App.svelte -->
<Widget>
	<h1 slot="header">Hello</h1>
	<p slot="footer">Copyright (c) 2019 Svelte Industries</p>
</Widget>

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

<!-- Widget.svelte -->
<div>
	<slot name="header">No header was provided</slot>
	<p>Some content between header and footer</p>
	<slot name="footer" />
</div>

<!-- App.svelte -->
<Widget>
	<HeaderComponent slot="header" />
	<svelte:fragment slot="footer">
		<p>All rights reserved.</p>
		<p>Copyright (c) 2019 Svelte Industries</p>
	</svelte:fragment>
</Widget>

$$slots

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

请注意,显式传递一个空命名槽会将该槽的名称添加到 $$slots 中。例如,如果父级将 <div slot="title" /> 传递给子组件,则 $$slots.title 在子组件中将为真。

<!-- Card.svelte -->
<div>
	<slot name="title" />
	{#if $$slots.description}
		<!-- This <hr> and slot will render only if a slot named "description" is provided. -->
		<hr />
		<slot name="description" />
	{/if}
</div>

<!-- App.svelte -->
<Card>
	<h1 slot="title">Blog Post Title</h1>
	<!-- No slot named "description" was provided so the optional slot will not be rendered. -->
</Card>

<slot key={value}>

槽可以被渲染零次或多次,并且可以使用道具将值传递父级。父级使用 let: 指令向槽模板公开值。

通常的速记规则适用——let:item 等效于 let:item={item},而 <slot {item}> 等效于 <slot item={item}>

<!-- FancyList.svelte -->
<ul>
	{#each items as item}
		<li class="fancy">
			<slot prop={item} />
		</li>
	{/each}
</ul>

<!-- App.svelte -->
<FancyList {items} let:prop={thing}>
	<div>{thing.text}</div>
</FancyList>

命名槽也可以公开值。let: 指令位于具有 slot 属性的元素上。

<!-- FancyList.svelte -->
<ul>
	{#each items as item}
		<li class="fancy">
			<slot name="item" {item} />
		</li>
	{/each}
</ul>

<slot name="footer" />

<!-- App.svelte -->
<FancyList {items}>
	<div slot="item" let:item>{item.text}</div>
	<p slot="footer">Copyright (c) 2019 Svelte Industries</p>
</FancyList>

<svelte:self>

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

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

<script>
	/** @type {number} */
	export let count;
</script>

{#if count > 0}
	<p>counting down... {count}</p>
	<svelte:self count={count - 1} />
{:else}
	<p>lift-off!</p>
{/if}

<svelte:component>

<svelte:component this={expression} />

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

如果 this 为假,则不渲染任何组件。

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

<svelte:element>

<svelte:element this={expression} />

<svelte:element> 元素允许你渲染一个动态指定类型的元素。例如,当从 CMS 显示富文本内容时,这很有用。将应用于元素的任何属性和事件侦听器。

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

如果 this 具有空值,则不会渲染元素及其子元素。

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

<script>
	let tag = 'div';

	export let handler;
</script>

<svelte:element this={tag} on:click={handler}>Foo</svelte:element>

<svelte:window>

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

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

<svelte:self> 不同,此元素只能出现在组件的顶层,并且永远不能位于块或元素中。

<script>
	/** @param {KeyboardEvent} event */
	function handleKeydown(event) {
		alert(`pressed the ${event.key} key`);
	}
</script>

<svelte:window on:keydown={handleKeydown} />

你还可以绑定到以下属性

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

除了 scrollXscrollY,其他都是只读的。

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

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

<svelte:document>

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

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

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

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

你还可以绑定到以下属性

  • fullscreenElement
  • visibilityState

所有都是只读的。

<svelte:body>

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

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

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

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

<svelte:head>

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

此元素可以将元素插入到 document.head 中。在服务器端渲染期间,head 内容会单独显示给主 html 内容。

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

<svelte:head>
	<title>Hello world!</title>
	<meta name="description" content="This is where the description goes for SEO" />
</svelte:head>

<svelte:options>

<svelte:options option={value} />

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

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

<svelte:fragment>

<svelte:fragment> 元素允许您将内容放入已命名插槽中,而无需将其包装在容器 DOM 元素中。这将保持文档的流布局完整无缺。

<!-- Widget.svelte -->
<div>
	<slot name="header">No header was provided</slot>
	<p>Some content between header and footer</p>
	<slot name="footer" />
</div>

<!-- App.svelte -->
<Widget>
	<h1 slot="header">Hello</h1>
	<svelte:fragment slot="footer">
		<p>All rights reserved.</p>
		<p>Copyright (c) 2019 Svelte Industries</p>
	</svelte:fragment>
</Widget>
上一个 组件指令
下一个 svelte