Skip to content

Update tutorial part 1 #274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ title: Welcome to Svelte

Welcome to the Svelte tutorial! This will teach you everything you need to know to easily build web applications of all sizes, with high performance and a small footprint.

You can also consult the [API docs](https://svelte.dev/docs) and the [examples](https://svelte.dev/examples), or — if you're impatient to start hacking on your machine locally — create a project with `npm init svelte`.
You can also consult the [API docs](https://svelte.dev/docs) and visit the [playground](https://svelte.dev/playground), or — if you're impatient to start hacking on your machine locally — create a project with `npx sv create`.

## What is Svelte?

Svelte is a tool for building web applications. Like other user interface frameworks, it allows you to build your app _declaratively_ out of components that combine markup, styles and behaviours.

These components are _compiled_ into small, efficient JavaScript modules that eliminate overhead traditionally associated with UI frameworks.

You can build your entire app with Svelte (for example, using an application framework like [SvelteKit](https://kit.svelte.dev), which this tutorial will cover), or you can add it incrementally to an existing codebase. You can also ship components as standalone packages that work anywhere.
You can build your entire app with Svelte (for example, using an application framework like [SvelteKit](/docs/kit), which this tutorial will cover), or you can add it incrementally to an existing codebase. You can also ship components as standalone packages that work anywhere.

## How to use this tutorial

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ Our image is missing a `src` — let's add one:

That's better. But if you hover over the `<img>` in the editor, Svelte is giving us a warning:

> A11y: &lt;img&gt; element should have an alt attribute
```
`<img>` element should have an alt attribute
```

When building web apps, it's important to make sure that they're _accessible_ to the broadest possible userbase, including people with (for example) impaired vision or motion, or people without powerful hardware or good internet connections. Accessibility (shortened to a11y) isn't always easy to get right, but Svelte will help by warning you if you write inaccessible markup.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ Add a `<script>` tag to the top of `App.svelte` that imports `Nested.svelte`...

Notice that even though `Nested.svelte` has a `<p>` element, the styles from `App.svelte` don't leak in.

> Component names are always capitalised, to distinguish them from HTML elements.
> Component names are capitalised, to distinguish them from HTML elements.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
let count = 0;

function increment() {
// event handler code goes here
// TODO implement
}
</script>

<button>
<button onclick={increment}>
Clicked {count}
{count === 1 ? 'time' : 'times'}
</button>
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script>
let count = 0;
let count = $state(0);

function increment() {
count += 1;
}
</script>

<button on:click={increment}>
<button onclick={increment}>
Clicked {count}
{count === 1 ? 'time' : 'times'}
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: State
---

At the heart of Svelte is a powerful system of _reactivity_ for keeping the DOM in sync with your application state — for example, in response to an event.

Make the `count` declaration reactive by wrapping the value with `$state(...)`:

```js
/// file: App.svelte
let count = +++$state(0)+++;
```

This is called a _rune_, and it's how you tell Svelte that `count` isn't an ordinary variable. Runes look like functions, but they're not — when you use Svelte, they're part of the language itself.

All that's left is to implement `increment`:

```js
/// file: App.svelte
function increment() {
+++count += 1;+++
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script>
let numbers = [1, 2, 3, 4];

function addNumber() {
// TODO implement
}
</script>

<p>{numbers.join(' + ')} = ...</p>

<button onclick={addNumber}>
Add a number
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script>
let numbers = $state([1, 2, 3, 4]);

function addNumber() {
numbers.push(numbers.length + 1);
}
</script>

<p>{numbers.join(' + ')} = ...</p>

<button onclick={addNumber}>
Add a number
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: Deep state
---

As we saw in the previous exercise, state reacts to _reassignments_. But it also reacts to _mutations_ — we call this _deep reactivity_.

Make `numbers` a reactive array:

```js
/// file: App.svelte
let numbers = +++$state([1, 2, 3, 4])+++;
```

Now, when we change the array...

```js
/// file: App.svelte
function addNumber() {
+++numbers[numbers.length] = numbers.length + 1;+++
}
```

...the component updates. Or better still, we can `push` to the array instead:

```js
/// file: App.svelte
function addNumber() {
+++numbers.push(numbers.length + 1);+++
}
```

> Deep reactivity is implemented using [proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), and mutations to the proxy do not affect the original object.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script>
let numbers = $state([1, 2, 3, 4]);
let total = $derived(numbers.reduce((t, n) => t + n, 0));

function addNumber() {
numbers.push(numbers.length + 1);
}
</script>

<p>{numbers.join(' + ')} = {total}</p>

<button onclick={addNumber}>
Add a number
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Derived state
---

Often, you will need to _derive_ state from other state. For this, we have the `$derived` rune:

```js
/// file: App.svelte
let numbers = $state([1, 2, 3, 4]);
+++let total = $derived(numbers.reduce((t, n) => t + n, 0));+++
```

We can now use this in our markup:

```svelte
/// file: App.svelte
<p>{numbers.join(' + ')} = +++{total}+++</p>
```

The expression inside the `$derived` declaration will be re-evaluated whenever its dependencies (in this case, just `numbers`) are updated. Unlike normal state, derived state is read-only.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script>
let elapsed = $state(0);
let interval = $state(1000);
</script>

<button onclick={() => interval /= 2}>speed up</button>
<button onclick={() => interval *= 2}>slow down</button>

<p>elapsed: {elapsed}</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script>
let elapsed = $state(0);
let interval = $state(1000);

$effect(() => {
const id = setInterval(() => {
elapsed += 1;
}, interval);

return () => {
clearInterval(id);
};
});
</script>

<button onclick={() => interval /= 2}>speed up</button>
<button onclick={() => interval *= 2}>slow down</button>

<p>elapsed: {elapsed}</p>
Loading
Loading