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/02-template-syntax.md

282 lines
6.3 KiB

---
title: Template syntax
---
Rather than reinventing the wheel, Svelte templates are built on foundations that have stood the test of time: HTML, CSS and JavaScript. There's very little extra stuff to learn.
### Tags
Tags allow you to bind data to your template. Whenever your data changes (for example after `component.a = 3`), the DOM updates automatically. You can use any JavaScript expression in templates, and it will also automatically update:
```html
<!-- { title: 'Template tags' } -->
<p>{a} + {b} = {a + b}</p>
```
```json
/* { hidden: true } */
{
"a": 1,
"b": 2
}
```
You can also use tags in attributes:
```html
<!-- { title: 'Tags in attributes' } -->
<h1 style="color: {color};">{color}</h1>
<p hidden={hideParagraph}>You can hide this paragraph.</p>
```
```json
/* { hidden: true } */
{
color: "steelblue",
hideParagraph: false
}
```
[Boolean attributes](https://www.w3.org/TR/html5/infrastructure.html#sec-boolean-attributes) like `hidden` will be omitted if the tag expression evaluates to false. Attributes will be removed from the element if their value is `undefined` or `null`.
### HTML
Ordinary tags render expressions as plain text. If you need your expression interpreted as HTML, wrap it in a special `@html` tag:
```html
<!-- { title: 'Triple tags' } -->
<p>This HTML: {content}</p>
<p>Renders as: {@html content}</p>
```
```json
/* { hidden: true } */
{
content: "Some <b>bold</b> text."
}
```
As with regular tags, you can use any JavaScript expression in HTML tags, and it will automatically update the document when your data changes.
> HTML is **not** sanitized before it is rendered! If you are displaying user input, you are responsible for first sanitizing it. Not doing so potentially opens you up to XSS attacks.
### If blocks
Control whether or not part of your template is rendered by wrapping it in an if block.
```html
<!-- { repl: false } -->
{#if user.loggedIn}
<a href="/logout">log out</a>
{/if}
{#if !user.loggedIn}
<a href="/login">log in</a>
{/if}
```
You can combine the two blocks above with `{:else}`:
```html
<!-- { repl: false } -->
{#if user.loggedIn}
<a href="/logout">log out</a>
{:else}
<a href="/login">log in</a>
{/if}
```
You can also use `{:else if ...}`:
```html
<!--{ title: 'If, else and else if' }-->
{#if x > 10}
<p>{x} is greater than 10</p>
{:else if 5 > x}
<p>{x} is less than 5</p>
{:else}
<p>{x} is between 5 and 10</p>
{/if}
```
```json
/* { hidden: true } */
{
x: 7
}
```
### Each blocks
Iterate over lists of data:
```html
<!--{ title: 'Each blocks' }-->
<h1>Cats of YouTube</h1>
<ul>
{#each cats as cat}
<li><a target="_blank" href={cat.video}>{cat.name}</a></li>
{:else}
<li>No cats :(</li>
{/each}
</ul>
```
```json
/* { hidden: true } */
{
cats: [
{
name: "Keyboard Cat",
video: "https://www.youtube.com/watch?v=J---aiyznGQ"
},
{
name: "Maru",
video: "https://www.youtube.com/watch?v=z_AbfPXTKms"
},
{
name: "Henri The Existential Cat",
video: "https://www.youtube.com/watch?v=OUtn3pvWmpg"
}
]
}
```
Else is triggered when the list is empty.
You can access the index of the current element with *expression* as *name*, *index*:
```html
<!--{ title: 'Each block indexes' }-->
<div class="grid">
{#each rows as row, y}
<div class="row">
{#each columns as column, x}
<code class="cell">
{x + 1},{y + 1}:
<strong>{row[column]}</strong>
</code>
{/each}
</div>
{/each}
</div>
```
```json
/* { hidden: true } */
{
columns: ["foo", "bar", "baz"],
rows: [
{ foo: "a", bar: "b", baz: "c" },
{ foo: "d", bar: "e", baz: "f" },
{ foo: "g", bar: "h", baz: "i" }
]
}
```
> By default, if the list `a, b, c` becomes `a, c`, Svelte will *remove* the third block and *change* the second from `b` to `c`, rather than removing `b`. If that's not what you want, use a [keyed each block](docs#keyed-each-blocks).
You can use destructuring patterns on the elements of the array:
```html
<!--{ title: 'Each block destructuring' }-->
<h1>It's the cats of YouTube again</h1>
<ul>
{#each cats as {name, video} }
<li><a target="_blank" href={video}>{name}</a></li>
{/each}
</ul>
```
```json
/* { hidden: true } */
{
cats: [
{
name: "Keyboard Cat",
video: "https://www.youtube.com/watch?v=J---aiyznGQ"
},
{
name: "Maru",
video: "https://www.youtube.com/watch?v=z_AbfPXTKms"
},
{
name: "Henri The Existential Cat",
video: "https://www.youtube.com/watch?v=OUtn3pvWmpg"
}
]
}
```
### Await blocks
You can represent the three states of a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — pending, fulfilled and rejected — with an `await` block:
```html
<!--{ title: 'Await blocks' }-->
<script>
const promise = new Promise(fulfil => {
setTimeout(() => fulfil(42), 3000);
});
</script>
{#await promise}
<p>wait for it...</p>
{:then answer}
<p>the answer is {answer}!</p>
{:catch error}
<p>well that's odd</p>
{/await}
```
If the expression in `{#await expression}` *isn't* a promise, Svelte skips ahead to the `then` section.
### Directives
Directives allow you to add special instructions for adding [event handlers](docs#event-handlers), [bindings](docs#bindings), [transitions](docs#transitions) and so on. We'll cover each of those in later stages of this guide for now, all you need to know is that directives can be identified by the `:` character:
```html
<!--{ title: 'Element directives' }-->
<p>Count: {count}</p>
<button on:click="{() => count += 1}">+1</button>
```
```json
/* { hidden: true } */
{
count: 0
}
```
> Technically, the `:` character is used to denote namespaced attributes in HTML. These will *not* be treated as directives, if encountered.
### Debug tags
To inspect data as it changes and flows through your app, use a `{@debug ...}` tag:
```html
<!--{ title: 'Debug tags' }-->
<input bind:value={name}>
{@debug name}
<h1>Hello {name}!</h1>
```
```json
/* { hidden: true } */
{
name: 'world'
}
```
This will log the value of `name` whenever it changes. If your devtools are open, changing `name` will pause execution and open the debugger.
You can debug multiple values simultaneously (`{@debug foo, bar, baz}`), or use `{@debug}` to pause execution whenever the surrounding markup is updated.
> Debug tags only have an effect when compiling with the `dev: true` compiler option.