Kurs Svelte i SvelteKit · Moduł 10: Akcje
Aktualizacja parametrów
W tej lekcji3
update() - Reaguj na zmiany parametrów
Akcja jest wywoływana tylko raz. Gdy parametr się zmieni, Svelte nie wywoła jej ponownie - zamiast tego wywoła metodę update() ze zwróconego obiektu, przekazując nową wartość:
export function tooltip(node, text) {
let tooltipEl;
let currentText = text;
// ... show/hide logic
return {
update(newText) {
currentText = newText;
if (tooltipEl) {
tooltipEl.textContent = newText;
}
},
destroy() {
// cleanup
}
};
}<script>
import { tooltip } from './actions.js';
let message = $state('Początkowy tekst');
</script>
<input bind:value={message} />
<button use:tooltip={message}>
Hover me
</button>Obiekt jako parametr
export function draggable(node, options = {}) {
let { axis = 'both', bounds = null } = options;
// ... logic
return {
update(newOptions) {
axis = newOptions.axis ?? 'both';
bounds = newOptions.bounds ?? null;
},
destroy() {
// cleanup
}
};
}<div use:draggable={{ axis: 'x', bounds: 'parent' }}>
Drag me horizontally
</div>Nowość: attachments ({@attach})
Od Svelte 5.29 zamiast akcji możesz użyć attachments. Attachment to funkcja, która dostaje element i może zwrócić funkcję sprzątającą. W przeciwieństwie do akcji jest w pełni reaktywny: gdy zmieni się stan użyty w jego wywołaniu, Svelte posprząta go i uruchomi ponownie, więc nie potrzebujesz update().
<script>
let message = $state('Początkowy tekst');
function tooltip(text) {
return (node) => {
node.title = text;
return () => node.removeAttribute('title');
};
}
</script>
<input bind:value={message} />
<button {@attach tooltip(message)}>Najedź na mnie</button>Akcje (use:) nadal są w pełni wspierane i znajdziesz je w wielu bibliotekach, dlatego w tej lokacji ćwiczymy właśnie je.
Kod do tej lekcji: App.svelte
<script>
// Akcje z eventami - click outside, longpress
import { clickOutside } from './actions.js';
import { longpress } from './actions.js';
let modalOpen = $state(false);
let message = $state('');
function handleClickOutside() {
modalOpen = false;
}
function handleLongpress() {
message = 'Long press wykryty!';
setTimeout(() => message = '', 2000);
}
</script>
<main class="actions-demo">
<h1>Actions z eventami</h1>
<section>
<h2>use:clickOutside</h2>
<button onclick={() => modalOpen = true}>Otwórz modal</button>
{#if modalOpen}
<div class="overlay">
<div class="modal" use:clickOutside onoutclick={handleClickOutside}>
<h3>Modal</h3>
<p>Kliknij poza mną, by zamknąć</p>
</div>
</div>
{/if}
</section>
<section>
<h2>use:longpress</h2>
<button
use:longpress={500}
onlongpress={handleLongpress}
>
Przytrzymaj 500ms
</button>
{#if message}
<p class="message">{message}</p>
{/if}
</section>
</main>
<style>
.actions-demo {
font-family: 'Georgia', serif;
max-width: 500px;
margin: 0 auto;
padding: 2rem;
background: #1a1a2e;
color: #e8e8f7;
min-height: 100vh;
}
h1 {
color: #7cb3f0;
text-align: center;
}
section {
background: rgba(124, 179, 240, 0.1);
border: 1px solid #7cb3f0;
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
}
h2 {
color: #7cb3f0;
font-size: 1rem;
margin-top: 0;
}
button {
padding: 0.75rem 1.5rem;
background: #3a5f8a;
color: #e8e8f7;
border: 1px solid #7cb3f0;
border-radius: 4px;
cursor: pointer;
}
.overlay {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.7);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
}
.modal {
background: #16213e;
border: 2px solid #7cb3f0;
border-radius: 8px;
padding: 2rem;
min-width: 300px;
text-align: center;
}
.modal h3 {
color: #7cb3f0;
margin-top: 0;
}
.message {
margin-top: 0.5rem;
padding: 0.5rem;
background: rgba(255, 215, 0, 0.2);
border-radius: 4px;
color: #ffd700;
}
</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. Która metoda w obiekcie zwracanym z action reaguje na zmiany parametrów?