Cours Svelte et SvelteKit · Module 8: Stores

Readable et Derived Stores

2 min de lecture ·
Dans cette leçon3

Readable Store

Un store en lecture seule - défini de l'extérieur :

import { readable } from 'svelte/store';

// Heure actuelle
export const time = readable(new Date(), function start(set) {
  const interval = setInterval(() => {
    set(new Date());
  }, 1000);

  // Nettoyage - lorsque le dernier abonné se désabonne
  return function stop() {
    clearInterval(interval);
  };
});

// Position de la souris
export const mousePosition = readable({ x: 0, y: 0 }, set => {
  function handler(e) {
    set({ x: e.clientX, y: e.clientY });
  }

  window.addEventListener('mousemove', handler);

  return () => {
    window.removeEventListener('mousemove', handler);
  };
});

Derived Store

Calculé à partir d'autres stores :

import { writable, derived } from 'svelte/store';

export const warriors = writable([
  { name: 'Ragnar', strength: 95 },
  { name: 'Bjorn', strength: 88 }
]);

// Dépendance unique
export const totalStrength = derived(
  warriors,
  $warriors => $warriors.reduce((sum, w) => sum + w.strength, 0)
);

// Dépendances multiples
export const gold = writable(100);
export const items = writable(5);

export const canBuy = derived(
  [gold, items],
  ([$gold, $items]) => $gold >= 50 && $items < 10
);

Derived asynchrone

export const asyncData = derived(
  userId,
  ($userId, set) => {
    set(null); // État de chargement

    fetch(`/api/user/${$userId}`)
      .then(r => r.json())
      .then(data => set(data));

    // Nettoyage optionnel
    return () => {};
  },
  null // Valeur initiale
);
Code de cette leçon : App.svelte
<script>
  // readable store - lecture seule
  import { time, elapsed } from './stores.js';
</script>

<main class="time-demo">
  <h1>⏰ readable store</h1>
  <p class="subtitle">Store en lecture seule</p>

  <section>
    <h2>Heure actuelle</h2>
    <div class="clock">{$time.toLocaleTimeString()}</div>
  </section>

  <section>
    <h2>Temps depuis le chargement</h2>
    <div class="elapsed">{$elapsed}s</div>
  </section>

  <section class="code">
    <h2>Comment ça marche ?</h2>
    <pre>
import {"{"} readable {"}"} from 'svelte/store';

export const time = readable(new Date(), set => {"{"}
  const interval = setInterval(() => {"{"}
    set(new Date());
  {"}"}, 1000);

  // Nettoyage
  return () => clearInterval(interval);
{"}"});
    </pre>
  </section>
</main>

<style>
  .time-demo {
    font-family: 'Georgia', serif;
    max-width: 500px;
    margin: 0 auto;
    padding: 2rem;
    background: #0a1628;
    color: #b8d4f7;
    min-height: 100vh;
  }

  h1 {
    color: #4a90d9;
    text-align: center;
  }

  .subtitle {
    text-align: center;
    color: #6a8ab9;
  }

  section {
    background: rgba(74, 144, 217, 0.1);
    border: 1px solid #4a90d9;
    border-radius: 8px;
    padding: 1rem;
    margin: 1rem 0;
  }

  h2 {
    color: #4a90d9;
    font-size: 1rem;
    margin-top: 0;
  }

  .clock {
    font-size: 3rem;
    font-family: monospace;
    text-align: center;
    color: #7cb3f0;
  }

  .elapsed {
    font-size: 2rem;
    font-family: monospace;
    text-align: center;
    color: #90ee90;
  }

  .code pre {
    background: rgba(0,0,0,0.5);
    padding: 1rem;
    border-radius: 4px;
    font-size: 0.85rem;
    overflow-x: auto;
  }
</style>

Entrées de la documentation utilisées dans cette leçon

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. En quoi un store readable diffère-t-il d'un store writable ?

Articles utiles