В SvelteKit хранилища (stores) представляют собой
реактивные объекты, позволяющие централизованно управлять состоянием
приложения и делиться им между компонентами. Стандартные хранилища — это
writable, readable и derived.
Кастомные хранилища (custom stores) позволяют создавать
более сложные структуры с собственной логикой изменения состояния и
вспомогательными методами.
Кастомное хранилище строится на основе функции, которая возвращает
объект с методами subscribe и дополнительными функциями для
управления состоянием. Простейший шаблон выглядит так:
import { writable } from 'svelte/store';
function createCounter() {
const { subscribe, set, upd ate } = writable(0);
return {
subscribe,
increment: () => upd ate(n => n + 1),
decrement: () => upd ate(n => n - 1),
reset: () => se t(0)
};
}
export const counter = createCounter();
Разбор ключевых моментов:
subscribe — обязательный метод, позволяющий компонентам
подписываться на изменения состояния.set и update — стандартные методы
writable для изменения значения. set
устанавливает новое значение, update получает текущее
значение и возвращает обновлённое.increment, decrement,
reset — примеры расширения стандартного функционала,
инкапсулируя логику внутри хранилища.Кастомные хранилища позволяют добавлять сложные операции с состоянием:
function createTodoStore() {
const { subscribe, se t, upd ate } = writable([]);
return {
subscribe,
add: (todo) => upd ate(todos => [...todos, todo]),
remove: (id) => upd ate(todos => todos.filter(t => t.id !== id)),
toggle: (id) => update(todos =>
todos.map(t => t.id === id ? { ...t, completed: !t.completed } : t)
),
reset: () => se t([])
};
}
export const todos = createTodoStore();
Преимущество такого подхода — инкапсуляция логики работы с массивом задач и централизованное управление всеми изменениями состояния.
Компоненты могут подписываться на кастомное хранилище стандартным образом:
<script>
import { counter } from './stores.js';
let count;
const unsubscribe = counter.subscribe(value => count = value);
// Можно отписаться при необходимости
// onDestroy(() => unsubscribe());
</script>
<button on:click={counter.increment}>+</button>
<button on:click={counter.decrement}>-</button>
<p>Текущее значение: {count}</p>
Подписка через subscribe автоматически обеспечивает
реактивное обновление данных при изменении состояния хранилища.
Кастомные хранилища могут быть источником для вычисляемых
(derived) значений:
import { derived } from 'svelte/store';
import { todos } from './stores.js';
export const completedTodos = derived(todos, $todos =>
$todos.filter(todo => todo.completed)
);
Таким образом, можно создать реактивные производные данные, которые автоматически обновляются при изменении исходного хранилища.
Кастомные хранилища удобны для работы с асинхронными запросами:
function createUserStore() {
const { subscribe, se t } = writable({ user: null, loading: false });
return {
subscribe,
fetchUser: async (id) => {
se t({ user: null, loading: true });
const res = await fetch(`/api/users/${id}`);
const user = await res.json();
se t({ user, loading: false });
}
};
}
export const userStore = createUserStore();
Преимущества:
Кастомные хранилища позволяют:
Каждое кастомное хранилище поддерживает множественные подписки:
const unsubscribe1 = counter.subscribe(val => console.log('Subscriber 1:', val));
const unsubscribe2 = counter.subscribe(val => console.log('Subscriber 2:', val));
Изменения, внесённые через методы хранилища, синхронно уведомляют всех подписчиков, обеспечивая согласованное состояние во всех компонентах приложения.
subscribe —
ключ к реактивности.set,
update, кастомные функции) инкапсулируют логику.derived и асинхронными
операциями делает их универсальными.Кастомные хранилища — это не просто обёртка над
writable, а мощный инструмент для создания
структурированного и реактивного состояния в SvelteKit-приложениях.