15 KiB
title |
---|
Run time |
svelte
The svelte
package exposes lifecycle functions and the context API.
onMount
onMount(callback: () => void)
onMount(callback: () => () => void)
The onMount
function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component's initialisation (but doesn't need to live inside the component; it can be called from an external module).
onMount
does not run inside a server-side component.
<script>
import { onMount } from 'svelte';
onMount(() => {
console.log('the component has mounted');
});
</script>
If a function is returned from onMount
, it will be called when the component is unmounted.
<script>
import { onMount } from 'svelte';
onMount(() => {
const interval = setInterval(() => {
console.log('beep');
}, 1000);
return () => clearInterval(interval);
});
</script>
beforeUpdate
beforeUpdate(callback: () => void)
Schedules a callback to run immediately before the component is updated after any state change.
The first time the callback runs will be before the initial
onMount
<script>
import { beforeUpdate } from 'svelte';
beforeUpdate(() => {
console.log('the component is about to update');
});
</script>
afterUpdate
afterUpdate(callback: () => void)
Schedules a callback to run immediately after the component has been updated.
<script>
import { afterUpdate } from 'svelte';
afterUpdate(() => {
console.log('the component just updated');
});
</script>
onDestroy
onDestroy(callback: () => void)
Schedules a callback to run once the component is unmounted.
Out of onMount
, beforeUpdate
, afterUpdate
and onDestroy
, this is the only one that runs inside a server-side component.
<script>
import { onDestroy } from 'svelte';
onDestroy(() => {
console.log('the component is being destroyed');
});
</script>
tick
promise: Promise = tick()
Returns a promise that resolves once any pending state changes have been applied, or in the next microtask if there are none.
<script>
import { beforeUpdate, tick } from 'svelte';
beforeUpdate(async () => {
console.log('the component is about to update');
await tick();
console.log('the component just updated');
});
</script>
setContext
setContext(key: any, context: any)
Associates an arbitrary context
object with the current component and the specified key
. The context is then available to children of the component (including slotted content) with getContext
.
Like lifecycle functions, this must be called during component initialisation.
<script>
import { setContext } from 'svelte';
setContext('answer', 42);
</script>
getContext
context: any = getContext(key: any)
Retrieves the context that belongs to the closest parent component with the specified key
. Must be called during component initialisation.
<script>
import { getContext } from 'svelte';
const answer = getContext('answer');
</script>
createEventDispatcher
TODO
svelte/store
The svelte/store
module exports functions for creating stores.
To be considered a store, an object must have a subscribe
method that returns an unsubscribe
function.
const unsubscribe = store.subscribe(value => {
console.log(value);
}); // logs `value`
// later...
unsubscribe();
Stores have special significance inside Svelte components. Their values can be read by prefixing the store's name with the $
character, which causes Svelte to set up subscriptions and unsubscriptions automatically during the component's lifecycle.
<script>
import { count } from './stores.js';
function handleClick() {
// this is equivalent to count.update(n => n + 1)
$count += 1;
}
</script>
<button on:click={handleClick}>
Clicks: {$count}
</button>
writable
store = writable(value: any)
store = writable(value: any, (set: (value: any) => void) => () => void)
Creates a store with additional set
and update
methods.
import { writable } from 'svelte/store';
const count = writable(0);
count.subscribe(value => {
console.log(value);
}); // logs '0'
count.set(1); // logs '1'
count.update(n => n + 1); // logs '2'
If a function is passed as the second argument, it will be called when the number of subscribers goes from zero to one (but not from one to two, etc). That function will be passed a set
function which changes the value of the store. It must return a stop
function that is called when the subscriber count goes from one to zero.
import { writable } from 'svelte/store';
const count = writable(0, () => {
console.log('got a subscriber');
return () => console.log('no more subscribers');
});
count.set(1); // does nothing
const unsubscribe = count.subscribe(value => {
console.log(value);
}); // logs 'got a subscriber', then '1'
unsubscribe(); // logs 'no more subscribers'
readable
store = readable(value: any, (set: (value: any) => void) => () => void)
Creates a store whose value cannot be set from 'outside', the first argument is the store's initial value.
The second argument to readable
is the same as the second argument to writable
, except that it is required with readable
(since otherwise there would be no way to update the store value).
import { readable } from 'svelte/store';
const time = readable(new Date(), set => {
const interval = setInterval(() => {
set(new Date());
}, 1000);
return () => clearInterval(interval);
});
derived
store = derived(a, callback: (a: any) => any)
store = derived(a, callback: (a: any, set: (value: any) => void) => void, initial_value: any)
store = derived([a, ...b], callback: ([a: any, ...b: any[]]) => any)
store = derived([a, ...b], callback: ([a: any, ...b: any[]], set: (value: any) => void) => void, initial_value: any)
Derives a store from one or more other stores. Whenever those dependencies change, the callback runs.
In the simplest version, derived
takes a single store, and the callback returns a derived value.
import { derived } from 'svelte/store';
const doubled = derived(a, $a => $a * 2);
The callback can set a value asynchronously by accepting a second argument, set
, and calling it when appropriate.
In this case, you can also pass a third argument to derived
— the initial value of the derived store before set
is first called.
import { derived } from 'svelte/store';
const delayed = derived(a, ($a, set) => {
setTimeout(() => set($a), 1000);
}, 'one moment...');
In both cases, an array of arguments can be passed as the first argument instead of a single store.
import { derived } from 'svelte/store';
const summed = derived([a, b], ([$a, $b]) => $a + $b);
const delayed = derived([a, b], ([$a, $b], set) => {
setTimeout(() => set($a + $b), 1000);
});
get
value: any = get(store)
Generally, you should read the value of a store by subscribing to it and using the value as it changes over time. Occasionally, you may need to retrieve the value of a store to which you're not subscribed. get
allows you to do so.
This works by creating a subscription, reading the value, then unsubscribing. It's therefore not recommended in hot code paths.
import { get } from 'svelte/store';
const value = get(store);
svelte/motion
The svelte/motion
module exports two functions, tweened
and spring
, for creating writable stores whose values change over time after set
and update
, rather than immediately.
tweened
store = tweened(value: any, options)
Tweened stores update their values over a fixed duration. The following options are available:
delay
(number
, default 0) — milliseconds before startingduration
(number
, default 400) — milliseconds the tween lastseasing
(function
, defaultt => t
) — an easing functioninterpolator
(function
) — see below
store.set
and store.update
can accept a second options
argument that will override the options passed in upon instantiation.
Both functions return a Promise that resolves when the tween completes. If the tween is interrupted, the promise will never resolve.
Out of the box, Svelte will interpolate between two numbers, two arrays or two objects (as long as the arrays and objects are the same 'shape', and their 'leaf' properties are also numbers).
<script>
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
const size = tweened(1, {
duration: 300,
easing: cubicOut
});
function handleClick() {
// this is equivalent to size.update(n => n + 1)
$size += 1;
}
</script>
<button
on:click={handleClick}
style="transform: scale({$size}); transform-origin: 0 0"
>embiggen</button>
The interpolator
option allows you to tween between any arbitrary values. It must be an (a, b) => t => value
function, where a
is the starting value, b
is the target value, t
is a number between 0 and 1, and value
is the result. For example, we can use the d3-interpolate package to smoothly interpolate between two colours.
<script>
import { interpolateLab } from 'd3-interpolate';
import { tweened } from 'svelte/motion';
const colors = [
'rgb(255, 62, 0)',
'rgb(64, 179, 255)',
'rgb(103, 103, 120)'
];
const color = tweened(colors[0], {
duration: 800,
interpolate: interpolateLab
});
</script>
{#each colors as c}
<button
style="background-color: {c}; color: white; border: none;"
on:click="{e => color.set(c)}"
>{c}</button>
{/each}
<h1 style="color: {$color}">{$color}</h1>
spring
store = spring(value: any, options)
A spring
store gradually changes to its target value based on its stiffness
and damping
parameters. Whereas tweened
stores change their values over a fixed duration, spring
stores change over a duration that is determined by their existing velocity, allowing for more natural-seeming motion in many situations. The following options are available:
stiffness
(number
, default0.15
) — a value between 0 and 1 where higher means a 'tighter' springdamping
(number
, default0.8
) — a value between 0 and 1 where lower means a 'springier' springprecision
(number
, default0.001
) — determines the threshold at which the spring is considered to have 'settled', where lower means more precise
As with tweened
stores, set
and update
return a Promise that resolves if the spring settles. The store.stiffness
and store.damping
properties can be changed while the spring is in motion, and will take immediate effect.
See a full example on the spring tutorial.
<script>
import { spring } from 'svelte/motion';
const coords = spring({ x: 50, y: 50 }, {
stiffness: 0.1,
damping: 0.25
});
</script>
svelte/transition
TODO
- fade, fly, slide, scale, draw
- crossfade...
svelte/animation
TODO
- TODO this doesn't even exist yet
TODO
svelte/easing
- TODO could have nice little interactive widgets showing the different functions, maybe
svelte/register
TODO
Client-side component API
Creating a component
const component = new Component(options)
A client-side component — that is, a component compiled with generate: 'dom'
(or the generate
option left unspecified) is a JavaScript class.
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
// assuming App.svelte contains something like
// `export let answer`:
answer: 42
}
});
The following initialisation options can be provided:
option | default | description |
---|---|---|
target |
none | An HTMLElement to render to. This option is required |
anchor |
null |
A child of target to render the component immediately before |
props |
{} |
An object of properties to supply to the component |
hydrate |
false |
See below |
intro |
false |
If true , will play transitions on initial render, rather than waiting for subsequent state changes |
Existing children of target
are left where they are.
The hydrate
option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the hydratable: true
option.
Whereas children of target
are normally left alone, hydrate: true
will cause any children to be removed. For that reason, the anchor
option cannot be used alongside hydrate: true
.
The existing DOM doesn't need to match the component — Svelte will 'repair' the DOM as it goes.
import App from './App.svelte';
const app = new App({
target: document.querySelector('#server-rendered-html'),
hydrate: true
});
$set
component.$set(props)
Programmatically sets props on an instance. component.$set({ x: 1 })
is equivalent to x = 1
inside the component's <script>
block.
Calling this method schedules an update for the next microtask — the DOM is not updated synchronously.
component.$set({ answer: 42 });
$on
component.$on(event, callback)
Causes the callback
function to be called whenever the component dispatches an event
.
app.$on('selected', event => {
console.log(event.detail.selection);
});
$destroy
component.$destroy()
Removes a component from the DOM and triggers any onDestroy
handlers.
Component props
component.prop
component.prop = value
If a component is compiled with accessors: true
, each instance will have getters and setters corresponding to each of the component's props. Setting a value will cause a synchronous update, rather than the default async update caused by component.$set(...)
.
By default, accessors
is false
, unless you're compiling as a custom element.
console.log(app.count);
app.count += 1;
Custom element API
- TODO
Server-side component API
const result = Component.render(...)
Unlike client-side components, server-side components don't have a lifespan after you render them — their whole job is to create some HTML and CSS. For that reason, the API is somewhat different.
A server-side component exposes a render
method that can be called with optional props. It returns an object with head
, html
, and css
properties, where head
contains the contents of any <svelte:head>
elements encountered.
const App = require('./App.svelte');
const { head, html, css } = App.render({
answer: 42
});