🎃

Nuxt.js(Bridge)でVuexからPiniaに移行する際の注意点と解決方法

2024/04/05に公開
4

Nuxt.js(Bridge)でVuexからPiniaに移行する際の注意点と解決方法

はじめに

こんにちは。今回は、Nuxt.js(Bridge)でVuexからPiniaに状態管理ライブラリを移行する際に詰まった点と、その解決方法について解説します。

今回紹介する内容は、以下のリポジトリで確認できますので、ぜひお役立てください。

https://github.com/NaokiHaba/nuxt-bridge-pinia

Piniaとは

Pinia は Vue.js 3から推奨されている新しい状態管理ライブラリです。Vuexよりもシンプルで使いやすく、TypeScriptとの相性も抜群です。

Nuxt.js(Bridge)でPiniaを使用する際の注意点

Nuxt.js(Bridge)
でPiniaを使用する際、特にサーバーサイドレンダリング(SSR)を行う場合には注意が必要です。以下のコードは、Nuxt.js(Bridge)
でPiniaを設定するための plugins/pinia.js ファイルの内容です。

なお、ここでは JavaScript を使用していますが、新たに構築する場合は TypeScript を使用することをおすすめします。

import { createPinia, setActivePinia } from 'pinia'

export default defineNuxtPlugin(nuxtApp => {
    const pinia = createPinia()
    nuxtApp.vueApp.use(pinia)
    setActivePinia(pinia)

    pinia._p.push(({ store }) => {
        Object.defineProperty(store, '$nuxtAxios', { value: nuxtApp.nuxt2Context.$axios })
    })

    if (process.server) {
        nuxtApp.nuxt2Context.beforeNuxtRender((ctx) => {
            ctx.nuxtState.pinia = pinia.state.value
        })
    } else if (nuxtApp.nuxt2Context.nuxtState && nuxtApp.nuxt2Context.nuxtState.pinia) {
        pinia.state.value = nuxtApp.nuxt2Context.nuxtState.pinia
    }

    return {
        provide: {
            pinia
        }
    }
})

このコードの重要なポイントは以下の2つです。

  1. サーバーサイドでPiniaの状態を nuxtState に保存する
  2. クライアントサイドで nuxtState からPiniaの状態を復元する

1. サーバーサイドでPiniaの状態を nuxtState に保存する

if (process.server) {
nuxtApp.nuxt2Context.beforeNuxtRender((ctx) => {
ctx.nuxtState.pinia = pinia.state.value
})
}

このコードは、サーバーサイドレンダリング時に実行されます。beforeNuxtRender フックを使用して、レンダリング直前にPiniaの現在の状態を nuxtState.pinia に保存しています。これにより、サーバーサイドで生成されたPiniaの状態をクライアントサイドに転送できます。

2. クライアントサイドで nuxtState からPiniaの状態を復元する

else if (nuxtApp.nuxt2Context.nuxtState && nuxtApp.nuxt2Context.nuxtState.pinia) {
pinia.state.value = nuxtApp.nuxt2Context.nuxtState.pinia
}

このコードは、クライアントサイドで実行されます。nuxtState.pinia が存在する場合、それをPiniaの状態として復元しています。これにより、サーバーサイドで生成されたPiniaの状態がクライアントサイドで正しく反映されます。

3. 複数のStoreを適切に紐づける方法

setActivePinia(pinia)を呼び出すことで、複数のStoreがそれぞれのStoreに適切に紐づくようにしています。これにより、各Storeが独立して動作し、互いに干渉しないようになります。

setActivePinia(pinia)は、Piniaのインスタンスを現在のアクティブなPiniaインスタンスとして設定します。これにより、useStoreなどのPiniaの関数が正しいStoreインスタンスを参照するようになります。

複数のStoreを使用する場合、それぞれのStoreが独立して動作することが重要です。setActivePinia(pinia)を呼び出すことで、各Storeが適切に分離され、互いに干渉しないようになります。

4. PiniaのプラグインにNuxtのコンテキストを渡す方法

デフォルトではPiniaは自身のStoreインスタンスのみを参照します。しかし、Piniaの内部プラグインに対してNuxtのコンテキストを渡したい場合があります。

このコードは、Piniaの内部プラグインを追加しています。プラグインは各Storeインスタンスに対して実行され、$nuxtAxiosプロパティを定義してNuxtのコンテキストを渡しています。

これにより、各StoreからNuxtのコンテキストにアクセスできるようになります。例えば、Storeの中でthis.$nuxtAxiosを使用してHTTPリクエストを送信することができます。

ただ、@nuxtjs/axios を使用している場合は、Fetch API 等への移行が必要なのでこちらのアプローチは不要です。

pinia._p.push(({ store }) => {
Object.defineProperty(store, '$nuxtAxios', { value: nuxtApp.nuxt2Context.$axios })
})

まとめ

Nuxt.js(Bridge)でPiniaを使用する際は、サーバーサイドレンダリングとの統合、複数のStoreの適切な紐づけ、Piniaプラグインへのコンテキスト渡し、TypeScriptとの統合など、いくつかの注意点があります。

今回紹介した内容を理解し、適切に対処することで、Nuxt.js(Bridge)でPiniaを効果的に活用し、アプリケーションの状態管理を改善することができるでしょう。

Piniaは強力で柔軟性の高い状態管理ライブラリであり、Nuxt.js(Bridge)との組み合わせにより、より効率的で保守性の高いアプリケーション開発が可能になります。

GitHubで編集を提案
Vue・Nuxt 情報が集まる広場 / Plaza for Vue・Nuxt.

Discussion