В SvelteKit stores представляют собой реактивный способ управления состоянием приложения, позволяя компонентам делиться данными без необходимости передавать их через пропсы. Stores обеспечивают централизованное хранение данных и автоматическое обновление компонентов при изменении состояния.
Svelte предлагает три основных типа встроенных
stores: writable, readable и
derived.
Writable store позволяет хранить изменяемое
состояние, которое можно читать и обновлять. Создание такого store
осуществляется через функцию writable из пакета
svelte/store:
import { writable } from 'svelte/store';
export const count = writable(0);
Ключевые методы writable:
subscribe(callback) – подписка на изменения состояния.
Возвращает функцию для отписки.set(value) – устанавливает новое значение store.upd ate(fn) – обновляет текущее значение с помощью
функции, принимающей текущее значение и возвращающей новое.Пример использования в компоненте:
<script>
import { count } from './stores.js';
function increment() {
count.update(n => n + 1);
}
</script>
<button on:click={increment}>
Увеличить: {$count}
</button>
Здесь $count — это реактивный синтаксис Svelte для
автоматической подписки на store. Любое изменение значения
count автоматически обновит отображение.
Readable store предназначен для хранения данных,
которые изменяются извне, например, при подписке на события или
получение данных с сервера. Такой store предоставляет только подписку,
без методов set и update для прямого
изменения.
Создание readable store:
import { readable } from 'svelte/store';
export const time = readable(new Date(), function start(se t) {
const interval = setInterval(() => {
set(new Date());
}, 1000);
return () => clearInterval(interval); // функция очистки при отписке
});
Ключевые особенности:
set внутри функции start используется для
обновления значения store.Использование в компоненте:
<p>Текущее время: {$time.toLocaleTimeString()}</p>
Derived store создается на основе одного или нескольких существующих stores и вычисляет производное состояние. Это удобно для агрегирования или трансформации данных.
Пример:
import { derived } from 'svelte/store';
import { count } from './stores.js';
export const doubled = derived(count, $count => $count * 2);
В компоненте:
<p>Двойное значение: {$doubled}</p>
Любые изменения count автоматически пересчитают значение
doubled.
Stores удобны для глобального состояния, когда
несколько компонентов должны реагировать на одни и те же данные. Можно
создавать отдельный файл stores.js и экспортировать все
stores:
import { writable, derived } from 'svelte/store';
export const user = writable({ name: 'Иван', loggedIn: false });
export const welcomeMessage = derived(user, $user =>
$user.loggedIn ? `Привет, ${$user.name}!` : 'Добро пожаловать!'
);
Использование в разных компонентах:
<p>{$welcomeMessage}</p>
Реактивный синтаксис $store позволяет автоматически
подписываться и отписываться от store. Для более сложной логики можно
использовать метод subscribe вручную:
import { count } from './stores.js';
const unsubscribe = count.subscribe(value => {
console.log('Текущее значение:', value);
});
// Отписка при необходимости
unsubscribe();
Stores отлично интегрируются с маршрутизацией SvelteKit, серверным рендерингом и асинхронными данными. Например, можно создавать store, который инициализируется данными с сервера:
import { writable } from 'svelte/store';
export const posts = writable([]);
export async function fetchPosts() {
const res = await fetch('/api/posts');
const data = await res.json();
posts.set(data);
}
В компоненте:
<script>
import { posts, fetchPosts } from './stores.js';
fetchPosts();
</script>
{#each $posts as post}
<p>{post.title}</p>
{/each}
Это позволяет хранить состояние независимо от компонентов, обеспечивая реактивность и согласованность данных по всему приложению.
Stores в SvelteKit представляют собой мощный инструмент для управления состоянием, позволяющий создавать реактивные и легко поддерживаемые приложения, минимизируя необходимость передачи данных через дерево компонентов и обеспечивая централизованное хранение логики состояния.