Pinia — это современная библиотека для управления состоянием в приложениях на Vue.js. Она пришла на смену Vuex, предлагая более простой и интуитивный API, полную поддержку TypeScript и интеграцию с Composition API. Pinia идеально подходит для проектов любого масштаба — от небольших SPA до крупных корпоративных решениях
Основные концепции
Состояние (State): Централизованное хранилище данных, доступное глобально во всех компонентах
Как создать:
javascript
// stores/counter.js
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
todos: [] as Todo[] // Явное указание типа в TypeScript
}),
});
interface Todo {
id: number;
text: string;
}
Геттеры (Getters): Функции для вычисления производных данных (аналогично computed
)
javascript
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
// Простой геттер через стрелочную функцию
doubleCount: (state) => state.count * 2,
// Геттер с использованием других геттеров (через this)
doublePlusOne(): number {
return this.doubleCount + 1;
},
// Геттер с параметром
getTodoById: (state) => (id: number) => state.todos.find(todo => todo.id === id)
}
});
Использование в компоненте:
<script setup>
const store = useCounterStore();
</script>
<template>
<p>Double: {{ store.doubleCount }}</p>
<p>Todo: {{ store.getTodoById(1)?.text }}</p>
</template>
Действия (Actions): Методы для изменения состояния (аналогично methods
)
Пример:
export const useCounterStore = defineStore('counter', {
actions: {
increment() {
this.count++; // Прямое изменение состояния
},
// Асинхронное действие (запрос к API)
async fetchTodos() {
try {
const response = await fetch('/api/todos');
this.todos = await response.json();
} catch (error) {
console.error('Ошибка загрузки:', error);
}
}
}
});
Пример создания хранилища:
javascriptimport { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
doubleCount: (state) => state.count * 2,
},
actions: {
increment() {
this.count++;
},
},
});
Ключевые преимущества
- Простота:
- Минимум шаблонного кода.
- Интуитивный синтаксис, близкий к Composition API.
- TypeScript: Автоматический вывод типов.
- Модульность: Каждое хранилище — отдельный модуль. Нет вложенных структур, как в Vuex.
- DevTools: Полная интеграция с Vue DevTools для отладки.
- Гибкость: Работает с Vue 2 (с
@vue/composition-api
) и Vue 3.
Сравнение с Vuex
Критерий | Pinia | Vuex |
---|---|---|
Синтаксис | Проще, меньше boilerplate | Более многословный |
TypeScript | Полная поддержка | Требует доп. конфигурации |
Модули | Автономные хранилища | Вложенные модули |
Размер | 1.5 KB (меньше Vuex) | 10 KB |
Когда использовать Pinia?
- Для централизации данных в крупных приложениях.
- Если нужна интеграция с Composition API.
- Для проектов с TypeScript.
- Для постепенной миграции с Vuex.
Пример использования
text<script setup>
import { useCounterStore } from '@/stores/counter';
const counter = useCounterStore();
</script>
<template>
<div>Текущий счёт: {{ counter.count }}</div>
<button @click="counter.increment()">+1</button>
<div>Удвоенное значение: {{ counter.doubleCount }}</div>
</template>
Советы
- Избегайте глобальных
ref
: Для сложных приложений Pinia надёжнее. - Используйте TypeScript: Для автодополнения и предотвращения ошибок.
- Плагины: Расширяйте функционал (например, синхронизация с LocalStorage).
Документация: pinia.vuejs.org
Сообщество: Активно развивается, рекомендовано командой Vue.js. Pinia — это эволюция управления состоянием во Vue. Она сочетает простоту, мощность и современные подходы, делая разработку быстрее и приятнее