Использование хранилища за пределами компонентов
Хранилища 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()
Самый простой способ обеспечить его постоянное применение - это отложить вызовы 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) => {
// ✅ Это будет работать, потому что маршрутизатор начинает свою навигацию после того,
// как router и pinia будут установлены
const store = useStore()
if (to.meta.requiresAuth && !store.isLoggedIn) return '/login'
})
SSR Apps
При работе с рендерингом на стороне сервера (SSR) вам придется передавать экземпляр pinia
функции useStore()
. Это предотвращает pinia от совместного использования глобального состояния между разными экземплярами приложения.
В руководстве по SSR есть целый раздел, посвященный этому, это всего лишь краткое объяснение.