Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между Pinia и Vuex
Vuex и Pinia — это библиотеки управления состоянием для Vue. Pinia — это современная альтернатива Vuex, которая стала официальной рекомендацией Vue Team. Вот основные различия.
1. Синтаксис и API
Pinia имеет более простой и интуитивный синтаксис, в то время как Vuex требует более боilerplate кода:
// Vuex — более сложный синтаксис
const store = createStore({
state() {
return {
count: 0,
user: null
}
},
mutations: {
INCREMENT(state) {
state.count++;
},
SET_USER(state, user) {
state.user = user;
}
},
actions: {
async fetchUser({ commit }, id) {
const user = await api.getUser(id);
commit("SET_USER", user);
}
},
getters: {
isUserAdmin: (state) => state.user?.role === "admin"
}
});
// Использование
store.commit("INCREMENT");
await store.dispatch("fetchUser", 1);
const admin = store.getters.isUserAdmin;
// Pinia — более простой синтаксис
import { defineStore } from "pinia";
const useCounterStore = defineStore("counter", {
state: () => ({
count: 0,
user: null
}),
getters: {
isUserAdmin: (state) => state.user?.role === "admin"
},
actions: {
increment() {
this.count++;
},
async fetchUser(id) {
this.user = await api.getUser(id);
}
}
});
// Использование
const store = useCounterStore();
store.increment();
await store.fetchUser(1);
const admin = store.isUserAdmin;
2. Mutations vs Actions
Vuex строго разделяет mutations (синхронные изменения) и actions (асинхронные операции). Pinia объединила их в actions:
// Vuex — нужно использовать и mutations, и actions
const store = createStore({
mutations: {
setCount(state, value) {
state.count = value;
}
},
actions: {
async updateCount({ commit }, newValue) {
const result = await api.fetch();
commit("setCount", result);
}
}
});
// Pinia — всё в actions
const useStore = defineStore("main", {
state: () => ({ count: 0 }),
actions: {
setCount(value) { // синхронное
this.count = value;
},
async updateCount() { // асинхронное
const result = await api.fetch();
this.count = result;
}
}
});
3. TypeScript поддержка
Pinia имеет встроенную и полноценную поддержку TypeScript, в то время как Vuex требует дополнительных типов:
// Pinia — нативная поддержка TypeScript
import { defineStore } from "pinia";
interface User {
id: number;
name: string;
role: "admin" | "user";
}
const useUserStore = defineStore("user", {
state: (): { user: User | null } => ({
user: null
}),
actions: {
setUser(user: User) {
this.user = user;
}
}
});
// Типы выводятся автоматически
const store = useUserStore();
store.user?.name; // TypeScript знает структуру
4. DevTools и отладка
Оба поддерживают DevTools, но Pinia имеет лучшую интеграцию и более удобный интерфейс:
// Vuex DevTools — видит только mutations и actions
store.commit("INCREMENT"); // видно в DevTools
store.dispatch("fetchData"); // видно в DevTools
// Pinia DevTools — видит все изменения состояния
store.count++; // видно в DevTools как изменение
store.actions(); // видно в DevTools
5. Производительность и размер бандла
Pinia значительно меньше по размеру (~8kb vs ~20kb для Vuex) и имеет лучшую производительность:
Vuex: ~20kb minified + gzip
Pinia: ~8kb minified + gzip
6. Модули vs Stores
Vuex использует модули для организации состояния, Pinia использует отдельные store функции, что проще:
// Vuex — модули
const store = createStore({
modules: {
user: {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
},
post: {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
}
});
store.state.user.name; // Вложенная структура
// Pinia — отдельные stores
const useUserStore = defineStore("user", { ... });
const usePostStore = defineStore("post", { ... });
const user = useUserStore();
const post = usePostStore();
user.name; // Более плоская структура
7. Hot Module Replacement (HMR)
Pinia имеет встроенную поддержку HMR без дополнительной конфигурации:
// Pinia — HMR работает автоматически
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useStore, import.meta.hot));
}
8. Composition API интеграция
Pinia отлично работает с Composition API, а Vuex требует дополнительного кода:
// Pinia с Composition API
import { useStore } from "./stores";
export function useUserComposable() {
const store = useStore();
return {
user: computed(() => store.user),
updateUser: () => store.updateUser()
};
}
// Vuex требует useStore и деструктуризации
import { useStore } from "vuex";
import { computed } from "vue";
export function useUserComposable() {
const store = useStore();
return {
user: computed(() => store.state.user),
updateUser: () => store.dispatch("updateUser")
};
}
9. Асинхронные операции и обработка ошибок
Pinia имеет более интуитивный способ обработки асинхронных операций:
// Pinia — прямое управление состоянием
const useStore = defineStore("main", {
state: () => ({ loading: false, error: null }),
actions: {
async fetchData() {
this.loading = true;
try {
const data = await api.fetch();
this.data = data;
} catch (error) {
this.error = error;
} finally {
this.loading = false;
}
}
}
});
10. Миграция с Vuex на Pinia
Vuex 5 будет официально заменена на Pinia. Миграция достаточно простая:
// Vuex
store.commit("INCREMENT");
store.dispatch("fetchUser", id);
const count = store.state.count;
// Pinia
store.increment();
await store.fetchUser(id);
const count = store.count;
Сравнительная таблица
| Критерий | Vuex | Pinia |
|---|---|---|
| Синтаксис | Сложный, многословный | Простой, интуитивный |
| TypeScript | Требует типов | Встроенная поддержка |
| Mutations/Actions | Раздельно | Объединено |
| Размер | ~20kb | ~8kb |
| Производительность | Хорошая | Отличная |
| HMR | Требует конфига | Встроено |
| DevTools | Да | Да, лучше |
| Официальный статус | Устаревает | Официальная рекомендация |
Вывод
Pinia — это современный выбор для новых проектов Vue. Она проще, меньше, быстрее и имеет лучшую TypeScript поддержку. Vuex всё ещё работает, но Vue Team рекомендует переходить на Pinia для новых приложений.