svelte/reactivity
Svelte fournit des versions réactives de différentes classes natives comme
Map
,
Set
et
URL
, qui peuvent être utilisées exactement
comme leur version native, ainsi qu’un certain nombre d’utilitaires permettant de bien gérer la
réactivité.
import {
class MediaQuery
Creates a media query and provides a current
property that reflects whether or not it matches.
Use it carefully — during server-side rendering, there is no way to know what the correct value should be, potentially causing content to change upon hydration.
If you can use the media query in CSS to achieve the same effect, do that.
<script>
import { MediaQuery } from 'svelte/reactivity';
const large = new MediaQuery('min-width: 800px');
</script>
<h1>{large.current ? 'large screen' : 'small screen'}</h1>
MediaQuery,
class SvelteDate
SvelteDate,
class SvelteMap<K, V>
SvelteMap,
class SvelteSet<T>
SvelteSet,
class SvelteURL
SvelteURL,
class SvelteURLSearchParams
SvelteURLSearchParams,
function createSubscriber(start: (update: () => void) => (() => void) | void): () => void
Returns a subscribe
function that, if called in an effect (including expressions in the template),
calls its start
callback with an update
function. Whenever update
is called, the effect re-runs.
If start
returns a function, it will be called when the effect is destroyed.
If subscribe
is called in multiple effects, start
will only be called once as long as the effects
are active, and the returned teardown function will only be called when all effects are destroyed.
It’s best understood with an example. Here’s an implementation of MediaQuery
:
import { createSubscriber } from 'svelte/reactivity';
import { on } from 'svelte/events';
export class MediaQuery {
#query;
#subscribe;
constructor(query) {
this.#query = window.matchMedia(`(${query})`);
this.#subscribe = createSubscriber((update) => {
// when the `change` event occurs, re-run any effects that read `this.current`
const off = on(this.#query, 'change', update);
// stop listening when all the effects are destroyed
return () => off();
});
}
get current() {
this.#subscribe();
// Return the current state of the query, whether or not we're in an effect
return this.#query.matches;
}
}
createSubscriber
} from 'svelte/reactivity';
MediaQuery
Disponible à partir de la version 5.7.0
Crée une media query et fournit une propriété current
qui reflète si oui ou non celle-ci
correspond.
Servez-vous en avec précaution — pendant le rendu côté serveur, il n’y a aucun moyen de connaître la valeur correcte, causant potentiellement des problèmes de contenu lors de l’hydratation. Si vous pouvez utiliser une media query en CSS pour obtenir le même résultat, faites-le.
<script>
import { MediaQuery } from 'svelte/reactivity';
const large = new MediaQuery('min-width: 800px');
</script>
<h1>{large.current ? 'écran large' : 'écran pas large'}</h1>
class MediaQuery extends ReactiveValue<boolean> {…}
constructor(query: string, fallback?: boolean | undefined);
query
Une chaîne de caractères de media queryfallback
Valeur de secours pour le serveur
SvelteDate
Une version réactive de l’objet natif
Date
. Lire
une SvelteDate
(que ce soit via des méthodes comme date.getTime()
ou date.toString()
, ou via
des choses comme
Intl.DateTimeFormat
)
dans un effet ou un dérivé va déclencher sa
ré-évaluation lorsque la valeur de la date change.
<script>
import { SvelteDate } from 'svelte/reactivity';
const date = new SvelteDate();
const formatter = new Intl.DateTimeFormat(undefined, {
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
});
$effect(() => {
const interval = setInterval(() => {
date.setTime(Date.now());
}, 1000);
return () => {
clearInterval(interval);
};
});
</script>
<p>The time is {formatter.format(date)}</p>
class SvelteDate extends Date {…}
constructor(...params: any[]);
SvelteMap
Une version réactive de l’objet natif
Map
.
Lire le contenu d’une SvelteMap
(en itérant, ou en lisant map.size
, ou en utilisant
map.get(...)
. ou map.has(...)
comme dans l’exemple de
morpion ci-dessous) dans un
effet ou un dérivé va déclencher sa ré-évaluation
si nécessaire lors de la mise à jour de la map.
Notez que les valeurs au sein d’une map réactive ne sont pas rendues profondément réactives.
<script>
import { SvelteMap } from 'svelte/reactivity';
import { result } from './game.js';
let board = new SvelteMap();
let player = $state('x');
let winner = $derived(result(board));
function reset() {
player = 'x';
board.clear();
}
</script>
<div class="board">
{#each Array(9), i}
<button
disabled={board.has(i) || winner}
onclick={() => {
board.set(i, player);
player = player === 'x' ? 'o' : 'x';
}}
>{board.get(i)}</button>
{/each}
</div>
{#if winner}
<p>{winner} gagne !</p>
<button onclick={reset}>recommencer</button>
{:else}
<p>C'est le tour de {player}</p>
{/if}
class SvelteMap<K, V> extends Map<K, V> {…}
constructor(value?: Iterable<readonly [K, V]> | null | undefined);
set(key: K, value: V): this;
SvelteSet
Une version réactive de l’objet natif
Set
.
Lire le contenu d’un SvelteSet
(en itérant, ou en lisant set.size
, ou en utilisant
set.has(...)
comme dans l’exemple ci-dessous) dans un
effet ou un dérivé va déclencher sa ré-évaluation
si nécessaire lors de la mise à jour du set.
Notez que les valeurs au sein d’un map réactif ne sont pas rendues profondément réactives.
<script>
import { SvelteSet } from 'svelte/reactivity';
let monkeys = new SvelteSet();
function toggle(monkey) {
if (monkeys.has(monkey)) {
monkeys.delete(monkey);
} else {
monkeys.add(monkey);
}
}
</script>
{#each ['🙈', '🙉', '🙊'] as monkey}
<button onclick={() => toggle(monkey)}>{monkey}</button>
{/each}
<button onclick={() => monkeys.clear()}>effacer</button>
{#if monkeys.has('🙈')}<p>ne pas voir le mal</p>{/if}
{#if monkeys.has('🙉')}<p>ne pas entendre le mal</p>{/if}
{#if monkeys.has('🙊')}<p>ne pas dire le mal</p>{/if}
class SvelteSet<T> extends Set<T> {…}
constructor(value?: Iterable<T> | null | undefined);
add(value: T): this;
SvelteURL
Une version réactive de l’objet natif
URL
. Lire des propriétés d’une SvelteURL
(comme url.href
ou url.pathname
) dans un effet ou un
dérivé va déclencher sa ré-évaluation si nécessaire lors de la mise à jour
de l’url.
La propriété searchParams
est une instance de
SvelteURLSearchParams.
<script>
import { SvelteURL } from 'svelte/reactivity';
const url = new SvelteURL('https://example.com/path');
</script>
<!-- les changements produits ici... -->
<input bind:value={url.protocol} />
<input bind:value={url.hostname} />
<input bind:value={url.pathname} />
<hr />
<!-- vont mettre à jour `url.href` et inversement -->
<input bind:value={url.href} size="65" />
class SvelteURL extends URL {…}
get searchParams(): SvelteURLSearchParams;
SvelteURLSearchParams
Une version réactive de l’objet natif
URLSearchParams
. Lire le contenu
d’un SvelteURLSearchParams
(en itérant, ou en appelant params.get(...)
ou params.getAll(...)
comme dans l’exemple ci-dessous) dans un
effet ou un dérivé va déclencher sa ré-évaluation
si nécessaire lors de la mise à jour des paramètres de recherche.
<script>
import { SvelteURLSearchParams } from 'svelte/reactivity';
const params = new SvelteURLSearchParams('message=hello');
let key = $state('key');
let value = $state('value');
</script>
<input bind:value={key} />
<input bind:value={value} />
<button onclick={() => params.append(key, value)}>ajouter</button>
<p>?{params.toString()}</p>
{#each params as [key, value]}
<p>{key}: {value}</p>
{/each}
class SvelteURLSearchParams extends URLSearchParams {…}
[REPLACE](params: URLSearchParams): void;
createSubscriber
Disponible à partir de la version 5.7.0
Renvoie une fonction subscribe
qui, si appelée dans un effet (incluant les expressions du
template), appelle son callback start
avec une fonction update
. Chaque fois que update
est
appelée, l’effect sera rejoué.
Si start
renvoie une fonction, celle-ci sera appelée lorsque l’effet sera détruit.
Si subscribe
est appelée dans plusieurs effets, start
ne sera appelé qu’une seule fois tant que
les effets sont actifs, et la fonction de “destruction” renvoyée ne sera appelée que lorsque tous
les effets concernées seront détruits.
On comprend mieux cette fonctionnalité avec un exemple. Voici l’implémentation de
MediaQuery
:
import { function createSubscriber(start: (update: () => void) => (() => void) | void): () => void
Returns a subscribe
function that, if called in an effect (including expressions in the template),
calls its start
callback with an update
function. Whenever update
is called, the effect re-runs.
If start
returns a function, it will be called when the effect is destroyed.
If subscribe
is called in multiple effects, start
will only be called once as long as the effects
are active, and the returned teardown function will only be called when all effects are destroyed.
It’s best understood with an example. Here’s an implementation of MediaQuery
:
import { createSubscriber } from 'svelte/reactivity';
import { on } from 'svelte/events';
export class MediaQuery {
#query;
#subscribe;
constructor(query) {
this.#query = window.matchMedia(`(${query})`);
this.#subscribe = createSubscriber((update) => {
// when the `change` event occurs, re-run any effects that read `this.current`
const off = on(this.#query, 'change', update);
// stop listening when all the effects are destroyed
return () => off();
});
}
get current() {
this.#subscribe();
// Return the current state of the query, whether or not we're in an effect
return this.#query.matches;
}
}
createSubscriber } from 'svelte/reactivity';
import { function on<Type extends keyof WindowEventMap>(window: Window, type: Type, handler: (this: Window, event: WindowEventMap[Type]) => any, options?: AddEventListenerOptions | undefined): () => void (+4 overloads)
Attaches an event handler to the window and returns a function that removes the handler. Using this
rather than addEventListener
will preserve the correct order relative to handlers added declaratively
(with attributes like onclick
), which use event delegation for performance reasons
on } from 'svelte/events';
export class class MediaQuery
MediaQuery {
#query;
#subscribe;
constructor(query: any
query) {
this.#query = var window: Window & typeof globalThis
window.function matchMedia(query: string): MediaQueryList
matchMedia(`(${query: any
query})`);
this.#subscribe = function createSubscriber(start: (update: () => void) => (() => void) | void): () => void
Returns a subscribe
function that, if called in an effect (including expressions in the template),
calls its start
callback with an update
function. Whenever update
is called, the effect re-runs.
If start
returns a function, it will be called when the effect is destroyed.
If subscribe
is called in multiple effects, start
will only be called once as long as the effects
are active, and the returned teardown function will only be called when all effects are destroyed.
It’s best understood with an example. Here’s an implementation of MediaQuery
:
import { createSubscriber } from 'svelte/reactivity';
import { on } from 'svelte/events';
export class MediaQuery {
#query;
#subscribe;
constructor(query) {
this.#query = window.matchMedia(`(${query})`);
this.#subscribe = createSubscriber((update) => {
// when the `change` event occurs, re-run any effects that read `this.current`
const off = on(this.#query, 'change', update);
// stop listening when all the effects are destroyed
return () => off();
});
}
get current() {
this.#subscribe();
// Return the current state of the query, whether or not we're in an effect
return this.#query.matches;
}
}
createSubscriber((update: () => void
update) => {
// lorsque l'évènement `change` se produit, rejoue tout effet qui lit `this.current`
const const off: () => void
off = on<MediaQueryList, "change">(element: MediaQueryList, type: "change", handler: (this: MediaQueryList, event: MediaQueryListEvent) => any, options?: AddEventListenerOptions | undefined): () => void (+4 overloads)
Attaches an event handler to an element and returns a function that removes the handler. Using this
rather than addEventListener
will preserve the correct order relative to handlers added declaratively
(with attributes like onclick
), which use event delegation for performance reasons
on(this.#query, 'change', update: () => void
update);
// arrête d'écouter lorsque tous les effets sont détruits
return () => const off: () => void
off();
});
}
get MediaQuery.current: boolean
current() {
this.#subscribe();
// renvoie l'état courant de la query, que l'on soit ou non dans un effet
return this.#query.MediaQueryList.matches: boolean
matches;
}
}
function createSubscriber(
start: (update: () => void) => (() => void) | void
): () => void;
Modifier cette page sur Github