mmag

ハマったことメモなど

VuexからPiniaへの乗り換え

BOLGの投稿画面はNuxt 2でできていて、3にするための準備で何度かNuxt Bridgeにするチャレンジをやっている。ただ毎回なにかしらがコケて成功しないので、もういっそのこと直接2から3へ上げてやろうということで、その準備としてのPinia移行。Vuex 4を使うという手もあるんだけど、どうせ移行作業するなら公式におすすめされてる方で。

Nuxt no longer provides a Vuex integration. Instead, the official Vue recommendation is to use pinia, which has built-in Nuxt support via a Nuxt module. Find out more about pinia here .

If you want to keep using Vuex, you can manually migrate to Vuex 4 following these steps .

https://v3.nuxtjs.org/migration/configuration/#vuex

Storeの移行

https://pinia.vuejs.org/core-concepts/ などを眺めながらやれば書き直しはわりと簡単。そこまで量は多くないんだけど後半は疲れたという程度。"arrow function recommended for full type inference"とのことなので、stateはアロー関数使っておきましょう。

https://pinia.vuejs.org/core-concepts/getters.html#with-setup でgetterにもmapStateが使えるよと書いてあるんだけど、一方で mapGettersもあるという点はおやおやポイントでした。

ちょっと注意が必要な点としては https://pinia.vuejs.org/ssr/nuxt.html#using-the-store-outside-of-setup にあるようにfetchasyncDataではstoreの作り方が他と違うというところ。ここの書き換えを忘れて500エラー出した。

fetch({ $pinia }) {
  const store = useStore($pinia)
}

nuxtServerInit

https://nuxtjs.org/docs/directory-structure/store/#the-nuxtserverinit-action

nuxtServerInitという名前のactionは特別扱いされていて、Vuexのストアに定義されていればリクエストが来たときにサーバ側で勝手に呼ばれます。Piniaでは呼ばれてくれないので、以下を参考にRouter middlewareで呼んであげます。勝手に呼ばれるときと違ってServer/Clientどちらでも呼ばれてしまうので、process.serverを見てあげましょう。

nuxtServerInit like implementation for Pinia · GitHub

// src/middleware/server-init.js

import { useStore } from '@/store'

const middleware = ({ $pinia, req }) => {
  if (process.server) {
    const store = useStore($pinia)
    store.nuxtServerInit({ req })
  }
}

export default middleware
// nuxt.config.js

router: {
  middleware: ['server-init'],
},

という感じで書き換えて、いまのところ動いています。