Skip to main content
Практика завдань

Pinia: управління станом у Vue.js

Що таке Pinia?

Pinia — це офіційна бібліотека управління станом для Vue.js (яка замінює Vuex). Вона забезпечує простий, типобезпечний спосіб управління глобальним станом з повною підтримкою Composition API та DevTools.


Визначення магазину

typescript
// stores/counter.ts import { defineStore } from 'pinia' import { ref, computed } from 'vue' // Стиль Composition API (рекомендується) export const useCounterStore = defineStore('counter', () => { // Стан const count = ref(0) const name = ref('Counter') // Геттери (computed) const doubleCount = computed(() => count.value * 2) // Дії (функції) function increment() { count.value++ } function decrement() { count.value-- } async function fetchCount() { const response = await fetch('/api/count') count.value = await response.json() } return { count, name, doubleCount, increment, decrement, fetchCount } })

Стиль Options API

typescript
// stores/user.ts export const useUserStore = defineStore('user', { state: () => ({ name: '', email: '', isLoggedIn: false, }), getters: { initials: (state) => state.name.split(' ').map(n => n[0]).join(''), }, actions: { async login(email: string, password: string) { const user = await api.login(email, password) this.name = user.name this.email = user.email this.isLoggedIn = true }, logout() { this.$reset() // Скидає стан до початкових значень }, }, })

Використання магазину в компонентах

vue
<script setup> import { useCounterStore } from '@/stores/counter' import { storeToRefs } from 'pinia' const counterStore = useCounterStore() // ✅ Використовуйте storeToRefs для реактивного деструктуризації const { count, doubleCount } = storeToRefs(counterStore) // Дії можна деструктуризувати безпосередньо const { increment, decrement } = counterStore </script> <template> <div> <p>Кількість: {{ count }}</p> <p>Подвійна: {{ doubleCount }}</p> <button @click="increment">+</button> <button @click="decrement">-</button> </div> </template>

storeToRefs

typescript
// ❌ Деструктуризація втрачає реактивність const { count } = useCounterStore() // count — це просто число, не реактивне // ✅ storeToRefs зберігає реактивність const { count } = storeToRefs(useCounterStore()) // count — це Ref<number>, реактивне

Спілкування між магазинами

typescript
// stores/cart.ts import { defineStore } from 'pinia' import { useUserStore } from './user' export const useCartStore = defineStore('cart', () => { const items = ref<CartItem[]>([]) function checkout() { const userStore = useUserStore() // Використання іншого магазину if (!userStore.isLoggedIn) { throw new Error('Необхідно увійти в систему') } // Обробка оформлення замовлення... } return { items, checkout } })

Pinia vs Vuex

ОсобливістьPiniaVuex
Стиль APIComposition + OptionsТільки Options
Мутації❌ Не потрібніОбов'язкові
TypeScript✅ Повна підтримка⚠️ Складна типізація
МодуліПлоскі магазини (простіше)Вкладені модулі
DevTools✅ Повна підтримка✅ Повна підтримка
Розмір пакету~1.5KB~10KB
Підтримка Vue 2Через плагінНативно

Важливо:

Pinia є рекомендуємим управлінням станом для Vue 3. Використовуйте стиль Composition API (defineStore з функцією setup) для найкращої підтримки TypeScript. Завжди використовуйте storeToRefs() при деструктуризації стану/геттерів для збереження реактивності. Pinia простіша за Vuex — без мутацій, плоскі магазини та відмінна інференція TypeScript.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань