Pinia store 依靠 pinia
實(shí)例在所有調(diào)用中共享同一個(gè) store 實(shí)例。大多數(shù)時(shí)候,只需調(diào)用你定義的 useStore()
函數(shù),完全開箱即用。例如,在 setup()
中,你不需要再做任何事情。但在組件之外,情況就有點(diǎn)不同了。
實(shí)際上,useStore()
給你的 app
自動(dòng)注入了 pinia
實(shí)例。這意味著,如果 pinia
實(shí)例不能自動(dòng)注入,你必須手動(dòng)提供給 useStore()
函數(shù)。
你可以根據(jù)不同的應(yīng)用,以不同的方式解決這個(gè)問(wèn)題。
如果你不做任何 SSR(服務(wù)器端渲染),在用 app.use(pinia)
安裝 pinia 插件后,對(duì) useStore()
的任何調(diào)用都會(huì)正常執(zhí)行:
import { useUserStore } from '@/stores/user'
import { createApp } from 'vue'
import App from './App.vue'
// ? 失敗,因?yàn)樗窃趧?chuàng)建 pinia 之前被調(diào)用的
const userStore = useUserStore()
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
// ? 成功,因?yàn)?pinia 實(shí)例現(xiàn)在激活了
const userStore = useUserStore()
為確保 pinia 實(shí)例被激活,最簡(jiǎn)單的方法就是將 useStore()
的調(diào)用放在 pinia 安
裝后才會(huì)執(zhí)行的函數(shù)中。
讓我們來(lái)看看這個(gè)在 Vue Router 的導(dǎo)航守衛(wèi)中使用 store 的例子。
import { createRouter } from 'vue-router'
const router = createRouter({
// ...
})
// ? 由于引入順序的問(wèn)題,這將失敗
const store = useStore()
router.beforeEach((to, from, next) => {
// 我們想要在這里使用 store
if (store.isLoggedIn) next()
else next('/login')
})
router.beforeEach((to) => {
// ? 這樣做是可行的,因?yàn)槁酚善魇窃谄浔话惭b之后開始導(dǎo)航的,
// 而此時(shí) Pinia 也已經(jīng)被安裝。
const store = useStore()
if (to.meta.requiresAuth && !store.isLoggedIn) return '/login'
})
當(dāng)處理服務(wù)端渲染時(shí),你將必須把 pinia
實(shí)例傳遞給 useStore()
。這可以防止 pinia 在不同的應(yīng)用實(shí)例之間共享全局狀態(tài)。
在SSR 指南中有一整節(jié)專門討論這個(gè)問(wèn)題,這里只是一個(gè)簡(jiǎn)短的解釋。
更多建議: