#svelte #javascript #frontend

Day 6: Components & Props

Welcome to Day 6. We’ve been working in one file. Real apps are trees of components.

Importing Components

It’s just standard module syntax.

<script>
  import Header from './Header.svelte';
  import Footer from './Footer.svelte';
</script>

<Header />
<main>...</main>
<Footer />

Props: $props()

In Svelte 5, we use the $props() rune to declare input. This essentially effectively replaces export let prop.

Child (UserCard.svelte)

<script lang="ts">
  // Destructure the props
  let { name, age = 18 } = $props(); 
</script>

<div class="card">
  <h2>{name}</h2>
  <p>Age: {age}</p>
</div>

Parent (App.svelte)

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

<UserCard name="Alice" age={25} />
<UserCard name="Bob" /> <!-- Uses default age 18 -->

Spread Props

You can pass an entire object.

<UserCard {...userData} />

Passing Functions (Event Handling)

Svelte 5 doesn’t use createEventDispatcher as much. Just pass a callback function as a prop!

Child (Button.svelte)

<script lang="ts">
  let { children, onClick } = $props();
</script>

<button onclick={onClick}>
  {@render children()}
</button>

Parent

<Button onClick={() => alert('Boom!')}>
  Click Me
</Button>

Challenge for Day 6

  1. Create Product.svelte.
  2. It accepts title (string) and price (number).
  3. It accepts an onAddToCart function prop.
  4. In App.svelte, verify you can click the button and see the log message from the parent.

Solution:

Product.svelte

<script lang="ts">
  let { title, price, onAddToCart } = $props();
</script>

<article>
  <h3>{title}</h3>
  <p>${price}</p>
  <button onclick={() => onAddToCart(title)}>Add</button>
</article>

App.svelte

<script>
  import Product from './Product.svelte';
  
  function handleAdd(item) {
    console.log("Added:", item);
  }
</script>

<Product title="Coffee" price={5} onAddToCart={handleAdd} />

Tomorrow we look at how to handle “children” content more robustly with Snippets.