Pinia 在組件外使用 store

2023-09-28 15:15 更新

Pinia store 依靠 pinia 實例在所有調(diào)用中共享同一個 store 實例。大多數(shù)時候,只需調(diào)用你定義的 useStore() 函數(shù),完全開箱即用。例如,在 setup() 中,你不需要再做任何事情。但在組件之外,情況就有點不同了。 實際上,useStore() 給你的 app 自動注入了 pinia 實例。這意味著,如果 pinia 實例不能自動注入,你必須手動提供給 useStore() 函數(shù)。 你可以根據(jù)不同的應(yīng)用,以不同的方式解決這個問題。

單頁面應(yīng)用

如果你不做任何 SSR(服務(wù)器端渲染),在用 app.use(pinia) 安裝 pinia 插件后,對 useStore() 的任何調(diào)用都會正常執(zhí)行:

import { useUserStore } from '@/stores/user'
import { createApp } from 'vue'
import App from './App.vue'


// ?  失敗,因為它是在創(chuàng)建 pinia 之前被調(diào)用的
const userStore = useUserStore()


const pinia = createPinia()
const app = createApp(App)
app.use(pinia)


// ? 成功,因為 pinia 實例現(xiàn)在激活了
const userStore = useUserStore()

為確保 pinia 實例被激活,最簡單的方法就是將 useStore() 的調(diào)用放在 pinia 安 裝后才會執(zhí)行的函數(shù)中。

讓我們來看看這個在 Vue Router 的導(dǎo)航守衛(wèi)中使用 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) => {
  // ? 這樣做是可行的,因為路由器是在其被安裝之后開始導(dǎo)航的,
  // 而此時 Pinia 也已經(jīng)被安裝。
  const store = useStore()


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

服務(wù)端渲染應(yīng)用

當處理服務(wù)端渲染時,你將必須把 pinia 實例傳遞給 useStore()。這可以防止 pinia 在不同的應(yīng)用實例之間共享全局狀態(tài)。

SSR 指南中有一整節(jié)專門討論這個問題,這里只是一個簡短的解釋。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號