在组件外使用存储

Pinia store 依靠 pinia 实例在所有调用中共享同一个 store 实例。 大多数情况下,只需调用您的“useStore()”函数即可开箱即用。 例如,在 setup() 中,您无需执行任何其他操作。 但在组件之外,情况有些不同。 在幕后,useStore() injects 你给你的apppinia 实例。 这意味着如果 pinia 实例无法自动注入,您必须手动将其提供给 useStore() 函数。 您可以根据您正在编写的应用程序的类型以不同的方式解决这个问题。

单页应用程序

如果您没有进行任何 SSR(服务器端渲染),则在使用 app.use(pinia) 安装 pinia 插件后,任何useStore() 调用都将起作用:

import { useUserStore } from '@/stores/user'
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 的导航守卫内部的 store 的例子:

import { createRouter } from 'vue-router'
const router = createRouter({
  // ...
})

// ❌ 根据导入的顺序,这将失败
const store = useStore()

router.beforeEach((to, from, next) => {
  // 我们想在这里使用 store 
  if (store.isLoggedIn) next()
  else next('/login')
})

router.beforeEach((to) => {
  // ✅ 这将起作用,因为路由器在之后开始导航
   // 路由已安装,pinia 也将安装
  const store = useStore()

  if (to.meta.requiresAuth && !store.isLoggedIn) return '/login'
})

服务端渲染应用

在处理服务器端渲染时,您必须将 pinia 实例传递给 useStore()。 这可以防止 pinia 在不同的应用程序实例之间共享全局状态。

SSR 指南 中有专门的一整节,这只是一个简短的解释: