Pinia в Nuxt
Pinia — официальная библиотека хранилищ для Vue, вы знаете её по курсу Vue. В Nuxt её подключают модулем @pinia/nuxt: он настраивает Pinia для отрисовки на сервере и передаёт состояние хранилищ в браузер. Pinia нужна, когда общего состояния становится много и рядом с данными появляются действия и вычисляемые значения.
Установка
npx nuxi module add piniaКоманда установит пакеты pinia и @pinia/nuxt и добавит модуль в настройки:
// nuxt.config.ts
export default defineNuxtConfig({
compatibilityDate: '2025-07-15',
modules: ['@pinia/nuxt']
})После перезапуска npm run dev функции defineStore и storeToRefs станут доступны без импорта.
Хранилище
Хранилища кладут в папку app/stores/. Создайте файл app/stores/favorites.ts — избранные статьи читателя:
// app/stores/favorites.ts
export const useFavoritesStore = defineStore('favorites', () => {
const ids = ref<number[]>([])
const count = computed(() => ids.value.length)
function toggle(id: number) {
if (ids.value.includes(id)) {
ids.value = ids.value.filter((item) => item !== id)
} else {
ids.value.push(id)
}
}
return { ids, count, toggle }
})Это хранилище в стиле setup: ref становится состоянием, computed — геттером, функция — действием.
Использование
Добавьте кнопку в карточку app/components/PostCard.vue:
<!-- app/components/PostCard.vue -->
<script setup lang="ts">
defineProps<{
post: { id: number; title: string; text: string }
}>()
const favorites = useFavoritesStore()
</script>
<template>
<article class="post-card">
<h3>{{ post.title }}</h3>
<button @click="favorites.toggle(post.id)">
{{ favorites.ids.includes(post.id) ? 'Убрать из избранного' : 'В избранное' }}
</button>
</article>
</template>И счётчик в шапке макета:
<!-- app/layouts/default.vue -->
<script setup lang="ts">
const favorites = useFavoritesStore()
</script>
<template>
<header>
<NuxtLink to="/posts">Статьи</NuxtLink>
<span>Избранное: {{ favorites.count }}</span>
</header>
</template>Отметьте две статьи на /posts — в шапке появится «Избранное: 2». Хранилища из app/stores/ модуль подключает автоматически; если в вашей версии модуля это не сработало, импортируйте явно: import { useFavoritesStore } from '~/stores/favorites'.
useState или Pinia
| Задача | Что выбрать |
|---|---|
| Одно-два простых значения | useState в composable |
| Данные вместе с действиями и вычислениями | Pinia |
| Нужно смотреть изменения в DevTools | Pinia |
Частая ошибка
Деструктуризация хранилища ломает реактивность: после const { count } = useFavoritesStore() переменная count навсегда останется равной начальному значению. Обращайтесь к полям через объект (favorites.count) или используйте storeToRefs: const { count } = storeToRefs(favorites). Действия можно доставать напрямую: const { toggle } = favorites.