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.
svelte/site/content/guide/06-special-components.md

136 lines
3.3 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

---
title: Special elements
---
Svelte includes a handful of built-in elements with special behaviour.
### `<svelte:self>`
Sometimes, a component needs to embed itself recursively — for example if you have a tree-like data structure. In Svelte, that's accomplished with the `<svelte:self>` tag:
```html
<!-- { title: '<svelte:self> tags' } -->
{#if countdown > 0}
<p>{countdown}</p>
<svelte:self countdown="{countdown - 1}"/>
{:else}
<p>liftoff!</p>
{/if}
```
```json
/* { hidden: true } */
{
countdown: 5
}
```
### `<svelte:component>`
If you don't know what kind of component to render until the app runs — in other words, it's driven by state (aka a dynamic component) — you can use `<svelte:component>`:
```html
<!-- { title: '<svelte:component> tags' } -->
<script>
import Red from './Red.html';
import Blue from './Blue.html';
let foo = true;
</script>
<input type=checkbox bind:checked={foo}> foo
<svelte:component this="{foo ? Red : Blue}" name="thing"/>
```
```html
<!--{ hidden: true, filename: 'Red.html' }-->
<p style="color: red">Red {name}</p>
```
```html
<!--{ hidden: true, filename: 'Blue.html' }-->
<p style="color: blue">Blue {name}</p>
```
The expression inside the `this="{...}"` can be any valid JavaScript expression.
### `<svelte:window>`
The `<svelte:window>` tag gives you a convenient way to declaratively add event listeners to `window`. Event listeners are automatically removed when the component is destroyed.
```html
<!-- { title: '<svelte:window> tags' } -->
<svelte:window on:keydown="{e => (key = event.key, keyCode = e.keyCode)}"/>
<style>
kbd {
background-color: #eee;
border: 2px solid #f4f4f4;
border-right-color: #ddd;
border-bottom-color: #ddd;
font-size: 2em;
margin: 0 0.5em 0 0;
padding: 0.5em 0.8em;
font-family: Inconsolata;
}
</style>
{#if key}
<p><kbd>{key === ' ' ? 'Space' : key}</kbd> (code {keyCode})</p>
{:else}
<p>click in this window and press any key</p>
{/if}
```
You can also bind to certain values — so far `innerWidth`, `outerWidth`, `innerHeight`, `outerHeight`, `scrollX`, `scrollY` and `online`:
```html
<!-- { title: '<svelte:window> bindings' } -->
<svelte:window bind:scrollY={y}/>
<style>
.background {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 9999px;
background: linear-gradient(to bottom, #7db9e8 0%,#0a1d33 100%);
}
.fixed {
position: fixed;
top: 1em;
left: 1em;
color: white;
}
</style>
<div class="background"></div>
<p class="fixed">user has scrolled {y} pixels</p>
```
### `<svelte:body>`
The `<svelte:body>` tag, just like `<svelte:window>`, gives you a convenient way to declaratively add event listeners to the `document.body` object. This is useful for listening to events that don't fire on `window`, such as `mouseenter` and `mouseleave`.
### `<svelte:head>`
If you're building an application with Svelte — particularly if you're using [Sapper](https://sapper.svelte.technology) — then it's likely you'll need to add some content to the `<head>` of your page, such as adding a `<title>` element.
You can do that with the `<svelte:head>` tag:
```html
<!-- { title: '<svelte:head> tags' } -->
<svelte:head>
<title>{post.title} • My blog</title>
</svelte:head>
```
When [server rendering](docs#server-side-rendering), the `<head>` contents can be extracted separately to the rest of the markup.