Olá, pessoal!
Com as Runes do Svelte 5, a forma de escrever componentes mudou um pouco. Queria compartilhar um guia prático de "antes e depois" para duas das alterações mais comuns que encontrei: a substituição do slot e do export let.
1.A Evolução do slot para {@render children}
O bom e velho slot foi substituído por uma abordagem mais explícita. O conteúdo que você passa para um componente agora é uma prop especial chamada children.
Antes (Svelte 4):
<script>
export let ativa = false; // Prop para controlar a classe
</script>
<div class="title" class:ativa>
<slot></slot>
</div>
Depois (Svelte 5): No novo modelo, acessamos children via $props() e usamos {@render} para exibi-lo.
<script lang="ts">
import type { Snippet } from 'svelte';
// "children" é a nova forma de acessar o conteúdo do <slot>
let { children, ativa = false } = $props();
</script>
<div class="title" class:ativa>
{@render children?.()}
</div>
2.Unificando Tudo: Props Dinâmicas com $props()
Agora, vamos adicionar uma prop para um elemento dinâmico. Antes, usávamos export let. Agora, tudo fica centralizado em $props().
Antes (Svelte 4): Componente que aceitava uma tag HTML dinâmica e conteúdo.
<script lang="ts">
export let tag: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
</script>
<svelte:element this={tag} class="titulo">
<slot></slot>
</svelte:element>
Depois (Svelte 5): A prop tag e o children (nosso antigo slot) são ambos acessados pelo mesmo $props(). Fica mais consistente!
<script lang="ts">
import type { Snippet } from 'svelte';
// Definimos um tipo para todas as nossas props
type Props = {
tag: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
children: Snippet;
};
// Pegamos tanto "tag" quanto "children" do $props()
let { children, tag }: Props = $props();
</script>
<svelte:element this={tag} class="titulo">
{@render children?.()}
</svelte:element>
Resumo Rápido
- export let para props ➡️ agora elas vêm de $props().
- slot ➡️ agora é a prop children vinda de $props().
- Para exibir o conteúdo do children ➡️ use {@render children}.