Kurs Svelte i SvelteKit · Moduł 4: Props i zdarzenia

Zaawansowane Props

2 min czytania ·
W tej lekcji5

Rest props

Zbierz pozostałe props do obiektu:

<script>
  // Wyciągnij name i weapon, resztę zbierz do 'rest'
  let { name, weapon, ...rest } = $props();
</script>

<div class="warrior" {...rest}>
  <h3>{name}</h3>
  <p>Broń: {weapon}</p>
</div>
<!-- Użycie - class, id i data-rank trafią do 'rest' -->
<Warrior
  name="Ragnar"
  weapon="Topór"
  class="elite"
  id="warrior-1"
  data-rank="jarl"
/>

Skrótowa składnia

Gdy nazwa zmiennej = nazwa prop:

<script>
  import Warrior from './Warrior.svelte';

  let name = 'Ragnar';
  let strength = 95;
</script>

<!-- Pełna składnia -->
<Warrior name={name} strength={strength} />

<!-- Skrótowa składnia -->
<Warrior {name} {strength} />

Props jako snippets (Svelte 5)

Treść między znacznikami komponentu trafia do propa children, a nazwane fragmenty definiujesz blokiem {#snippet}. Komponent wyświetla je tagiem {@render} (w Svelte 4 robiły to sloty, <slot />):

<!-- Card.svelte -->
<script>
  let { header, children } = $props();
</script>

<div class="card">
  <header>{@render header()}</header>
  <main>{@render children()}</main>
</div>
<!-- Użycie -->
<Card>
  {#snippet header()}
    <h2>Nagłówek karty</h2>
  {/snippet}

  <p>Zawartość karty</p>
</Card>

Reaktywne props

Props są automatycznie reaktywne:

<!-- Parent.svelte -->
<script>
  import Barracks from './Barracks.svelte';

  let warriorCount = $state(5);
</script>

<Barracks count={warriorCount} />
<button onclick={() => warriorCount++}>Dodaj</button>
<!-- Barracks.svelte -->
<script>
  let { count } = $props();

  // count aktualizuje się automatycznie gdy zmieni się w rodzicu!
  let doubled = $derived(count * 2);
</script>

<p>Wojownicy: {count}, Podwojeni: {doubled}</p>

Walidacja props w runtime

<script>
  let { name, strength = 50 } = $props();

  // Wypisuje strength w konsoli przy każdej zmianie (tylko w trybie deweloperskim)
  $inspect(strength);

  $effect(() => {
    if (strength < 0 || strength > 100) {
      console.warn(`Nieprawidłowa siła: ${strength}`);
    }
  });
</script>
Kod do tej lekcji: App.svelte
<script>
  // Advanced props: spread {...warrior} and a callback prop
  import WarriorCard from './WarriorCard.svelte';

  let warriors = $state([
    { id: 1, name: 'Ragnar', role: 'Berserker', level: 45 },
    { id: 2, name: 'Lagertha', role: 'Shieldmaiden', level: 42 },
    { id: 3, name: 'Bjorn', role: 'Viking', level: 38 }
  ]);

  function levelUp(id) {
    const warrior = warriors.find(w => w.id === id);
    // Deep $state: changing a field updates every card that shows it
    warrior.level += 1;
  }
</script>

<main class="hall">
  <h1>Warriors Hall</h1>
  <p>{'{...warrior}'} passes every field of the object as a prop</p>

  <div class="grid">
    {#each warriors as warrior (warrior.id)}
      <WarriorCard {...warrior} onLevelUp={levelUp} />
    {/each}
  </div>
</main>

<style>
  .hall {
    font-family: 'Georgia', serif;
    max-width: 800px;
    margin: 0 auto;
    padding: 2rem;
    background: #1a0f0a;
    color: #e8d5b7;
    min-height: 100vh;
  }

  h1 {
    color: #d4af37;
    text-align: center;
  }

  p {
    text-align: center;
    color: #8b7355;
  }

  .grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
    margin-top: 2rem;
  }
</style>

Hasła z dokumentacji w tej lekcji

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Jak użyć skrótowej składni gdy nazwa zmiennej = nazwa prop?

  2. 2. Jak przekazać wszystkie właściwości obiektu jako props?

Przydatne artykuły