Svelte is a modern JavaScript framework for building user interfaces. Unlike frameworks, Svelte does not use a virtual DOM. Instead, it compiles components to efficient code that manipulates the DOM directly.
Introduction
Installing Svelte
To get started with Svelte, you need to install the initial environment using npx
:
npx degit sveltejs/template project-name
cd project-name
npm install
This creates a base project and runs a development server.
Starting a development server
Once installed, you can start a development server to see the project in action:
npm run dev
Components in Svelte
Creating a component
A component in Svelte is a .svelte
file that includes HTML, CSS, and JavaScript.
<script>
let name = 'World';
</script>
<h1>Hello {name}!</h1>
<style>
h1 {
color: blue;
}
</style>
<script>
: JavaScript logic<style>
: CSS styles (scoped by default)- HTML: The markup that renders the component.
Dynamic rendering
Variables in Svelte are rendered within HTML using curly braces {}
.
<h1>{name}</h1>
Props
Passing props to components
Data can be passed from a parent component to a child component using props.
Child component:
<script>
export let name;
</script>
<p>Hello, {name}!</p>
Parent component:
<ChildComponent name="Svelte" />
Default values in props
<script>
export let name = "World";
</script>
<p>Hello, {name}!</p>
Reactivity
Reactive variables
Variables in Svelte are automatically reactive, meaning any change in their value triggers a re-render.
<script>
let counter = 0;
</script>
<button on:click="{() => counter++}">
Counter: {counter}
</button>
Reactive assignment
Svelte allows you to create reactive statements with the $:
symbol.
<script>
let width = 100;
$: area = width * width;
</script>
<p>The area is: {area}</p>
Reactivity of arrays and objects
Svelte detects changes in specific properties of objects or arrays through reassignment.
<script>
let obj = { x: 10, y: 20 };
function changeX() {
obj.x = 50; // Not reactive
obj = { ...obj }; // This is reactive
}
</script>
Events and Bindings
Listening to events
Events can be captured with the on:
directive.
<button on:click={increment}>
Increment
</button>
Event modifiers
Modifiers can be added to events, such as preventDefault
or stopPropagation
:
<form on:submit|preventDefault="{submitForm}">
<!-- Form here -->
</form>
Event forwarding
Components can forward events to the parent component:
<!-- ChildComponent.svelte -->
<button on:click>Click me</button>
<!-- ParentComponent.svelte -->
<ChildComponent on:click={() => alert('Clicked!')} />
Two-way binding
Svelte allows two-way binding of variables between inputs and components.
<input bind:value={name} />
<p>{name}</p>
Loops and Conditionals
if Conditionals
<script>
let visible = true;
</script>
{#if visible}
<p>This text is visible</p>
{:else}
<p>It's not visible</p>
{/if}
Loops
Loops in Svelte are managed with each
:
<script>
let fruits = ['Apple', 'Banana', 'Cherry'];
</script>
<ul>
{#each fruits as fruit}
<li>{fruit}</li>
{/each}
</ul>
Styles
CSS in components
Each component in Svelte can have its own styles, which apply only to that component (automatic scope).
<style>
h1 {
color: green;
}
</style>
Global styles
To apply global styles, the :global
keyword is used.
<style>
:global(body) {
font-family: Arial, sans-serif;
}
</style>
Stores in Svelte
Creating a store
Stores allow sharing state between components. Stores can be created using Svelte’s writable
module.
import { writable } from 'svelte/store';
export const counter = writable(0);
Using stores in components
A store can be subscribed to a component using the $
symbol:
<script>
import { counter } from './store.js';
</script>
<button on:click="{() => $counter++}">
Counter: {$counter}
</button>
Writable store
<script>
import { writable } from 'svelte/store';
let counter = writable(0);
</script>
<button on:click={() => counter.update(n => n + 1)}>
Increment counter
</button>
<p>Counter value: {$counter}</p>
Readable store
Read-only stores (readable
) are useful for constant values or values that change externally.
<script>
import { readable } from 'svelte/store';
const time = readable(new Date(), set => {
const interval = setInterval(() => set(new Date()), 1000);
return () => clearInterval(interval);
});
</script>
<p>The time is: {$time}</p>
Component Lifecycle
Svelte offers several functions to manage a component’s lifecycle.
onMount
Runs when the component is mounted in the DOM.
<script>
import { onMount } from 'svelte';
onMount(() => {
console.log('Component mounted');
});
</script>
beforeUpdate
Runs before each update.
<script>
import { beforeUpdate } from 'svelte';
beforeUpdate(() => {
console.log('Before update');
});
</script>
afterUpdate
Runs after each update.
<script>
import { afterUpdate } from 'svelte';
afterUpdate(() => {
console.log('After update');
});
</script>
onDestroy
Runs when the component is destroyed.
<script>
import { onDestroy } from 'svelte';
onDestroy(() => {
console.log('Component destroyed');
});
</script>
Transitions and Animations
Entry and exit transitions
Svelte has built-in transitions to animate the entry and exit of elements.
<script>
import { fade } from 'svelte/transition';
let visible = true;
</script>
<button on:click={() => (visible = !visible)}>
Toggle
</button>
{#if visible}
<p in:fade>Hello</p>
{/if}
Custom animations
You can create custom transitions for elements.
<script>
import { fly } from 'svelte/transition';
</script>
<p in:fly={{ x: 200, duration: 400 }}>Animated</p>
Animations
To move elements in the DOM, Svelte has animations using the animate
module.
<script>
import { flip } from 'svelte/animate';
let items = [1, 2, 3];
</script>
<ul>
{#each items as item (item)}
<li animate:flip>{item}</li>
{/each}
</ul>
Context API
The context API allows passing data between components without using props.
Setting context
<script context="module">
import { setContext } from 'svelte';
setContext('key', value);
</script>
Getting context
<script>
import { getContext } from 'svelte';
const value = getContext('key');
</script>