Skip to content
On this page

コンポーネント外部でストアを使用する

Pinia ストアは、すべての呼び出しで同じストアインスタンスを共有するために、pinia インスタンスに依存しています。ほとんどの場合、useStore() 関数を呼び出すだけで、すぐに動作するようになります。例えば、setup() では、他に何もする必要はありません。しかし、コンポーネントの外では少し事情が異なります。 裏側では、useStore()app に与えた pinia インスタンスを 注入 しています。つまり、pinia インスタンスを自動的に注入できない場合は、手動で useStore() 関数に提供する必要があります。 作成しているアプリケーションの種類に応じて、これを別の方法で解決できます。

シングルページアプリケーション

SSR(Server Side Rendering)を行っていない場合、app.use(pinia) を使用して pinia プラグインをインストールした後の useStore() の呼び出しは機能します:

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

// ❌  fails because it's called before the pinia is created
const userStore = useUserStore()

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

// ✅ works because the pinia instance is now active
const userStore = useUserStore()
import { useUserStore } from '@/stores/user'
import { createApp } from 'vue'
import App from './App.vue'

// ❌  fails because it's called before the pinia is created
const userStore = useUserStore()

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

// ✅ works because the pinia instance is now active
const userStore = useUserStore()

これが常に適用されるようにする最も簡単な方法は、pinia のインストール後に常に実行される関数内に useStore() を配置して、呼び出しを 遅延 させることです。

Vue Router でナビゲーションガード内のストアを使用する例を見てみましょう:

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

// ❌ Depending on the order of imports this will fail
const store = useStore()

router.beforeEach((to, from, next) => {
  // we wanted to use the store here
  if (store.isLoggedIn) next()
  else next('/login')
})

router.beforeEach((to) => {
  // ✅ This will work because the router starts its navigation after
  // the router is installed and pinia will be installed too
  const store = useStore()

  if (to.meta.requiresAuth && !store.isLoggedIn) return '/login'
})
import { createRouter } from 'vue-router'
const router = createRouter({
  // ...
})

// ❌ Depending on the order of imports this will fail
const store = useStore()

router.beforeEach((to, from, next) => {
  // we wanted to use the store here
  if (store.isLoggedIn) next()
  else next('/login')
})

router.beforeEach((to) => {
  // ✅ This will work because the router starts its navigation after
  // the router is installed and pinia will be installed too
  const store = useStore()

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

SSR アプリ

Server Side Rendering を扱う場合、useStore()pinia インスタンスを渡す必要があります。これにより、pinia が異なるアプリケーションのインスタンス間でグローバルなステートを共有することを防ぎます。

SSR ガイド に専用のセクションがあるので、ここでは簡単に説明します:

Released under the MIT License.