Використання сховища поза компонентом
Сховища Pinia покладаються на екземпляр pinia
для спільного використання одного екземпляра сховища для всіх викликів. У більшості випадків це працює з коробки, просто викликаючи вашу функцію useStore()
. Наприклад, у setup()
вам більше нічого не потрібно робити. Але поза компонентом все трохи інакше. За лаштунками useStore()
вводить екземпляр pinia
, який ви надали своєму app
. Це означає, що якщо екземпляр pinia
не може бути автоматично введений, ви маєте вручну надати його функції useStore()
. Ви можете вирішити це по-різному залежно від типу застосунку, який ви пишете.
Односторінкові застосунки
Якщо ви не виконуєте SSR (рендеринг на стороні серверу), будь-який виклик useStore()
після встановлення плагіна pinia за допомогою app.use(pinia)
працюватиме:
import { useUserStore } from '@/stores/user'
import { createPinia } from 'pinia';
import { createApp } from 'vue'
import App from './App.vue'
// ❌ завершиться невдало, тому що воно викликано до створення pinia
const userStore = useUserStore()
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
// ✅ працює, оскільки екземпляр pinia зараз активний
const userStore = useUserStore()
import { useUserStore } from '@/stores/user'
import { createPinia } from 'pinia';
import { createApp } from 'vue'
import App from './App.vue'
// ❌ завершиться невдало, тому що воно викликано до створення pinia
const userStore = useUserStore()
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
// ✅ працює, оскільки екземпляр pinia зараз активний
const userStore = useUserStore()
Найпростіший спосіб переконатися, що це завжди застосовується, це відкласти виклики useStore()
шляхом розміщення їх у функціях, які завжди запускатимуться після встановлення pinia.
Давайте подивимося на цей приклад використання сховища всередині навігаційного охоронця за допомогою Vue Router:
import { createRouter } from 'vue-router'
const router = createRouter({
// ...
})
// ❌ Залежно від порядку імпорту це не вдасться
const store = useStore()
router.beforeEach((to, from, next) => {
// ми хотіли скористатися сховищем тут
if (store.isLoggedIn) next()
else next('/login')
})
router.beforeEach((to) => {
// ✅ Це спрацює, оскільки маршрутизатор починає свою навігацію після
// встановлення маршрутизатора, а pinia також буде встановлено
const store = useStore()
if (to.meta.requiresAuth && !store.isLoggedIn) return '/login'
})
import { createRouter } from 'vue-router'
const router = createRouter({
// ...
})
// ❌ Залежно від порядку імпорту це не вдасться
const store = useStore()
router.beforeEach((to, from, next) => {
// ми хотіли скористатися сховищем тут
if (store.isLoggedIn) next()
else next('/login')
})
router.beforeEach((to) => {
// ✅ Це спрацює, оскільки маршрутизатор починає свою навігацію після
// встановлення маршрутизатора, а pinia також буде встановлено
const store = useStore()
if (to.meta.requiresAuth && !store.isLoggedIn) return '/login'
})
SSR застосунки
При роботі з рендерингом на стороні сервера вам доведеться передати екземпляр pinia
в useStore()
. Це перешкоджає pinia обмінюватися глобальним станом між різними екземплярами програми.
У посібнику з SSR цьому присвячений цілий розділ, це лише коротке пояснення.