mirror of https://github.com/sveltejs/svelte
				
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							347 lines
						
					
					
						
							10 KiB
						
					
					
				
			
		
		
	
	
							347 lines
						
					
					
						
							10 KiB
						
					
					
				| ---
 | |
| title: Special elements
 | |
| ---
 | |
| 
 | |
| ## `<slot>`
 | |
| 
 | |
| ```svelte
 | |
| <slot><!-- optional fallback --></slot>
 | |
| ```
 | |
| 
 | |
| ```svelte
 | |
| <slot name="x"><!-- optional fallback --></slot>
 | |
| ```
 | |
| 
 | |
| ```svelte
 | |
| <slot prop={value} />
 | |
| ```
 | |
| 
 | |
| Components can have child content, in the same way that elements can.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| ```svelte
 | |
| <!-- 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>
 | |
| ```
 | |
| 
 | |
| 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.
 | |
| 
 | |
| ```svelte
 | |
| <!-- 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>
 | |
| ```
 | |
| 
 | |
| 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>`.
 | |
| 
 | |
| ```svelte
 | |
| <!-- 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` 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| ```svelte
 | |
| <!-- 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_`}>`
 | |
| 
 | |
| 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.
 | |
| 
 | |
| The usual shorthand rules apply — `let:item` is equivalent to `let:item={item}`, and `<slot {item}>` is equivalent to `<slot item={item}>`.
 | |
| 
 | |
| ```svelte
 | |
| <!-- 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>
 | |
| ```
 | |
| 
 | |
| Named slots can also expose values. The `let:` directive goes on the element with the `slot` attribute.
 | |
| 
 | |
| ```svelte
 | |
| <!-- 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>`
 | |
| 
 | |
| The `<svelte:self>` element allows a component to include itself, recursively.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| ```svelte
 | |
| <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
 | |
| <svelte:component this={expression} />
 | |
| ```
 | |
| 
 | |
| 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.
 | |
| 
 | |
| If `this` is falsy, no component is rendered.
 | |
| 
 | |
| ```svelte
 | |
| <svelte:component this={currentSelection.component} foo={bar} />
 | |
| ```
 | |
| 
 | |
| ## `<svelte:element>`
 | |
| 
 | |
| ```svelte
 | |
| <svelte:element this={expression} />
 | |
| ```
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| If `this` has a nullish value, the element and its children will not be rendered.
 | |
| 
 | |
| If `this` is the name of a [void element](https://developer.mozilla.org/en-US/docs/Glossary/Void_element) (e.g., `br`) and `<svelte:element>` has child elements, a runtime error will be thrown in development mode.
 | |
| 
 | |
| ```svelte
 | |
| <script>
 | |
| 	let tag = 'div';
 | |
| 
 | |
| 	export let handler;
 | |
| </script>
 | |
| 
 | |
| <svelte:element this={tag} on:click={handler}>Foo</svelte:element>
 | |
| ```
 | |
| 
 | |
| ## `<svelte:window>`
 | |
| 
 | |
| ```svelte
 | |
| <svelte:window on:event={handler} />
 | |
| ```
 | |
| 
 | |
| ```svelte
 | |
| <svelte:window bind:prop={value} />
 | |
| ```
 | |
| 
 | |
| 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.
 | |
| 
 | |
| Unlike `<svelte:self>`, this element may only appear at the top level of your component and must never be inside a block or element.
 | |
| 
 | |
| ```svelte
 | |
| <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`
 | |
| - `online` — an alias for `window.navigator.onLine`
 | |
| - `devicePixelRatio`
 | |
| 
 | |
| All except `scrollX` and `scrollY` are readonly.
 | |
| 
 | |
| ```svelte
 | |
| <svelte:window bind:scrollY={y} />
 | |
| ```
 | |
| 
 | |
| > Note that the page will not be scrolled to the initial value to avoid accessibility issues. Only subsequent changes to the bound variable of `scrollX` and `scrollY` will cause scrolling. However, if the scrolling behaviour is desired, call `scrollTo()` in `onMount()`.
 | |
| 
 | |
| ## `<svelte:document>`
 | |
| 
 | |
| ```svelte
 | |
| <svelte:document on:event={handler} />
 | |
| ```
 | |
| 
 | |
| ```svelte
 | |
| <svelte:document bind:prop={value} />
 | |
| ```
 | |
| 
 | |
| 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](/docs/element-directives#use-action) on `document`.
 | |
| 
 | |
| 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
 | |
| <svelte:document on:visibilitychange={handleVisibilityChange} use:someAction />
 | |
| ```
 | |
| 
 | |
| You can also bind to the following properties:
 | |
| 
 | |
| - `fullscreenElement`
 | |
| - `visibilityState`
 | |
| 
 | |
| All are readonly.
 | |
| 
 | |
| ## `<svelte:body>`
 | |
| 
 | |
| ```svelte
 | |
| <svelte:body on:event={handler} />
 | |
| ```
 | |
| 
 | |
| 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](/docs/element-directives#use-action) on the `<body>` element.
 | |
| 
 | |
| 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
 | |
| <svelte:body on:mouseenter={handleMouseenter} on:mouseleave={handleMouseleave} use:someAction />
 | |
| ```
 | |
| 
 | |
| ## `<svelte:head>`
 | |
| 
 | |
| ```svelte
 | |
| <svelte:head>...</svelte:head>
 | |
| ```
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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
 | |
| <svelte:head>
 | |
| 	<title>Hello world!</title>
 | |
| 	<meta name="description" content="This is where the description goes for SEO" />
 | |
| </svelte:head>
 | |
| ```
 | |
| 
 | |
| ## `<svelte:options>`
 | |
| 
 | |
| ```svelte
 | |
| <svelte:options option={value} />
 | |
| ```
 | |
| 
 | |
| The `<svelte:options>` element provides a place to specify per-component compiler options, which are detailed in the [compiler section](/docs/svelte-compiler#compile). The possible options are:
 | |
| 
 | |
| - `immutable={true}` — you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed
 | |
| - `immutable={false}` — the default. Svelte will be more conservative about whether or not mutable objects have changed
 | |
| - `accessors={true}` — adds getters and setters for the component's props
 | |
| - `accessors={false}` — the default
 | |
| - `namespace="..."` — the namespace where this component will be used, most commonly "svg"; use the "foreign" namespace to opt out of case-insensitive attribute names and HTML-specific warnings
 | |
| - `customElement="..."` — the name to use when compiling this component as a custom element
 | |
| 
 | |
| ```svelte
 | |
| <svelte:options customElement="my-custom-element" />
 | |
| ```
 | |
| 
 | |
| ## `<svelte:fragment>`
 | |
| 
 | |
| The `<svelte:fragment>` element allows you to place content in a [named slot](/docs/special-elements#slot-slot-name-name) without wrapping it in a container DOM element. This keeps the flow layout of your document intact.
 | |
| 
 | |
| ```svelte
 | |
| <!-- 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>
 | |
| ```
 |