A quickdive into Svelte
I've been learning Svelte. Here are my notes as I learned it!
I’ve been learning Svelte. Here are my notes as I learned it! If you’re already familiar with JavaScript and other frameworks, I’m hoping this guide can help you learn Svelte quickly. 👇
Svelte basics
Introduction
Svelte is a web framework for writing rich user interfaces.
Basic component
Svelte components store the markup, script and CSS styles in one .svelte
file.
<script>
let name = "Rico";
</script>
<div>
hello {name}!
</div>
<style>
div { color: dodgerblue; }
</style>
Nested components
Using export let
will define a component property.
<script>
import Nested from './Nested.svelte';
</script>
<div>
My message is:
<Nested message="Hello there" />
</div>
<script>
export let message;
</script>
<div>
{message}
</div>
<style>
div { color: purple; }
</style>
Styling
Styles are scoped per component, but :global(…)
will allow styling elements outside the component.
<p>
Only this will be red.
</p>
<style>
p { color: red; }
p :global(a) { color: blue; }
</style>
Attributes markup
Attributes are in HTML syntax, and can contain JavaScript expressions inside {…}
brackets.
<img src={src}>
<img src="{src}">
<img src="https://{src}">
<img {src}> <!-- shorthand -->
<img {...props}> <!-- spread -->
State
State & events
Updating variables declared with let
will trigger DOM updates.
<script>
let count = 0; // state
</script>
<button on:click={() => { count++ }}>
I was clicked {count} times
</button>
Computed state
Prefixing statements with $:
will make it run with changes to the states it depends on.
<script>
let count;
// reactive state derived from `count`
$: doubled = count * 2;
</script>
Reactive statements
$:
works with blocks too. Only values which directly appear within the $: block will become dependencies of the reactive statement.
<script>
// runs when the `title` prop changes
$: document.title = title;
// reactive block
$: {
console.log('title is', title);
}
</script>
Template syntax
If conditionals (#if
)
{#if answer === 42}
Yes
{/if}
Else-if and else (:else
)
{#if answer === 42 && a !== b}
Yes
{:else if answer === 74 || b > c}
Maybe
{:else}
No
{/if}
Loops (#each
)
{#each items as item}
<li>{item.name} x {item.qty}</li>
{/each}
<!-- With index: -->
{#each items as item, index}
<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}
Loops with keys
The key expression allows for efficient adding and removing of items.
{#each users as user (user.id)}
<UserCard {user} />
{/each}
Text markup
Text expressions are automatically escaped unless @html
is used.
<p>{string}</p>
<p>{@html string}</p>
Forms
Text inputs
bind:value
forms a two-way binding to a state variable.
<script>
let name = '';
</script>
<label>
Name:
<input bind:value={name} />
</label>
<p>Hello {name || 'stranger'}!</p>
Checkboxes
bind:checked
binds the checked state of a checkbox to a state variable.
<script>
let subscribed = false;
</script>
<label>
<input bind:checked={subscribed} />
Subscribe to the newsletter
</label>
{#if subscribed}
<p>Thank you for subscribing!</p>
{/if}
Radio buttons
bind:group
binds a variable to a group of elements, such as a radio button group.
<script>
let flavor;
</script>
<fieldset>
Flavor:
<input type='radio'
bind:group={flavor} value='vanilla'>
<input type='radio'
bind:group={flavor} value='mint'>
</fieldset>
Special components
Head elements
<svelte:head>
allows inserting elements into the document head.
<svelte:head>
<meta name="robots" content="noindex">
</svelte:head>
Body events
<svelte:body>
allows binding DOM events to the body element.
<svelte:body
on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave}
use:someAction
/>
Window props
svelte:window
allows manipulating window properties.
<svelte:window
bind:innerWidth={width}
/>
innerWidth
innerHeight
outerWidth
outerHeight
scrollX
(rw)scrollY
(rw)online
Window events
<svelte:window>
also allows binding DOM events to the window
object.
<svelte:window
on:keydown={handleKeydown}
/>
Slots
Slots
Slots allow passing content to a component (“children”).
<script>
import Notice from './Notice.svelte'
</script>
<Notice>
There will be rain today.
</Notice>
<div class='notice'>
<strong>Notice:</strong>
<slot></slot>
</div>
Named slots
Use named slots to pass more than 1 group of children elements.
<MyDialog>
<h1 slot='header'>Forecast:</h1>
There will be rain today.
<div slot='footer'>23°C, Rain</div>
</MyDialog>
<dialog class='my-dialog'>
<header>
<slot name='header'></slot>
</header>
<slot></slot>
<footer>
<slot name='footer'></slot>
</footer>
</dialog>
Fragments in named slots
<svelte:fragment slot="items">
<li>Apple</li>
<li>Banana</li>
<li>Cherry</li>
</svelte:fragment>
<slot name="items"></slot>
Slot props
<slot prop={value}></slot>
Slot fallbacks
<slot prop={value}>
This is fallback content
</slot>
Other features
bind:this
<script>
import { onMount } from 'svelte';
let canvasEl;
onMount(() => {
drawOn(canvasEl.getContext('2d'));
});
</script>
<canvas bind:this={canvasEl}></canvas>
Docs: bind:this