Skip to main content

模板语法

特殊元素

<slot>

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

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

Components can have child content, in the same way that elements can.

使用 <slot> 元素在子组件中公开内容,该元素可以包含在未提供子组件时渲染的后备内容。

The content is exposed in the child component using the <slot> element, which can contain fallback content that is rendered if no children are provided.

<!-- 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" />

Note: If you want to render regular <slot> element, You can use <svelte:element this="slot" />.

<slot name="name">

命名槽允许消费者瞄准特定区域。 他们还可以有后备内容。

Named slots allow consumers to target specific areas. They can also have fallback content.

<!-- 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>

Components can be placed in a named slot using the syntax <Component slot="name" />. In order to place content in a slot without using a wrapper element, you can use the special element <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 is an object whose keys are the names of the slots passed into the component by the parent. If the parent does not pass in a slot with a particular name, that name will not be present in $$slots. This allows components to render a slot (and other elements, like wrappers for styling) only if the parent provides it.

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

Note that explicitly passing in an empty named slot will add that slot's name to $$slots. For example, if a parent passes <div slot="title" /> to a child component, $$slots.title will be truthy within the child.

<!-- 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}>

插槽可以渲染零次或多次,并且可以使用 props 将值传递回父级。 父级使用 let: 指令将值公开给槽模板。

Slots can be rendered zero or more times and can pass values back to the parent using props. The parent exposes the values to the slot template using the let: directive.

适用通常的速记规则 — let:item 相当于 let:item={item}<slot {item}> 相当于 <slot item={item}>

The usual shorthand rules apply — let:item is equivalent to let:item={item}, and <slot {item}> is equivalent to <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 属性的元素上。

Named slots can also expose values. The let: directive goes on the element with the slot attribute.

<!-- 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> 元素允许组件递归地包含其自身。

The <svelte:self> element allows a component to include itself, recursively.

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

It cannot appear at the top level of your markup; it must be inside an if or each block or passed to a component's slot to prevent an infinite loop.

<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 属性的组件构造函数动态渲染组件。 当属性更改时,组件将被销毁并重新创建。

The <svelte:component> element renders a component dynamically, using the component constructor specified as the this property. When the property changes, the component is destroyed and recreated.

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

If this is falsy, no component is rendered.

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

<svelte:element>

<svelte:element this={expression} />

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

The <svelte:element> element lets you render an element of a dynamically specified type. This is useful for example when displaying rich text content from a CMS. Any properties and event listeners present will be applied to the element.

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

The only supported binding is bind:this, since the element type-specific bindings that Svelte does at build time (e.g. bind:value for input elements) do not work with a dynamic tag type.

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

If this has a nullish value, the element and its children will not be rendered.

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

If this is the name of a void element (e.g., br) and <svelte:element> has child elements, a runtime error will be thrown in development mode.

<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 是否存在。

The <svelte:window> element allows you to add event listeners to the window object without worrying about removing them when the component is destroyed, or checking for the existence of window when server-side rendering.

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

Unlike <svelte:self>, this element may only appear at the top level of your component and must never be inside a block or element.

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

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

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

You can also bind to the following properties:

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

scrollXscrollY 之外的所有内容都是只读的。

All except scrollX and scrollY are readonly.

<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 上使用 actions

Similarly to <svelte:window>, this element allows you to add listeners to events on document, such as visibilitychange, which don't fire on window. It also lets you use actions on document.

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

As with <svelte:window>, this element may only appear the top level of your component and must never be inside a block or element.

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

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

You can also bind to the following properties:

  • fullscreenElement
  • visibilityState

全部都是只读的。

All are readonly.

<svelte:body>

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

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

Similarly to <svelte:window>, this element allows you to add listeners to events on document.body, such as mouseenter and mouseleave, which don't fire on window. It also lets you use actions on the <body> element.

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

As with <svelte:window> and <svelte:document>, this element may only appear the top level of your component and must never be inside a block or element.

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

<svelte:head>

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

该元素使得可以将元素插入到 document.head 中。 在服务器端渲染期间,head 内容单独暴露于主要 html 内容。

This element makes it possible to insert elements into document.head. During server-side rendering, head content is exposed separately to the main html content.

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

As with <svelte:window>, <svelte:document> and <svelte:body>, this element may only appear at the top level of your component and must never be inside a block or element.

<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> 元素提供了一个指定每个组件编译器选项的位置,这些选项在 编译器部分.h 中有详细说明。 可能的选项有:

The <svelte:options> element provides a place to specify per-component compiler options, which are detailed in the compiler section. The possible options are:

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

<svelte:fragment>

<svelte:fragment> 元素允许你将内容放置在 命名槽 中,而无需将其封装在容器 DOM 元素中。 这可以保持文档的流程布局完好无损。

The <svelte:fragment> element allows you to place content in a named slot without wrapping it in a container DOM element. This keeps the flow layout of your document intact.

<!-- 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