Closed8
Nuxt 2環境化で Pinia / Vuexを共存させて移行するメモ
Nuxt2 -> Nuxt3にあげれない状況下(主にフレームワークに引っ張られてる)ため、VuexをPiniaに移行しつつNuxt3へアップデートを段階的に行うために調べたメモをスクラップする
Piniaを動かすためには、以下をインストールするのが前提
- Vue2.7系を直接インストールする
- compositionAPIを入れる
- Vue-demiが必要
- TypeScriptが必要(ビルド時にコケる)
修正が必要な部分
- 既存コードdefineStoreで this参照できないようなので、
this.axios.$get
などは axiosをインポートしてしてaxios.get
に書き換えが必要
Nuxt2配下だと以下のエラーが発生する
Can't import the named export from non EcmaScript module (only default export is available
nuxt.configのbuildの設定をいじらないといけない
build: {
extend(config) {
config.module.rules.push({
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
})
},
},
},
Nuxt2の既存コードにPiniaを挿入していくため、ページ層だったりは従来のOptions APIを利用することが前提移行完了後にsetupに書き直す必要があるが完全移行前は以下のドキュメントに書いている内容で変更を加えていく
例えば stateをテンプレートに出したい場合は以下のように書く
<template>
<div>
{{ user }}
</div>
</template>
<script>
import { mapState } from 'pinia'
import { useUsersStore } form '{path}/stores/XXXX'
export default {
computed: {
...mapState(useUsersStore, {
user: 'user'
// 続く
})
}
}
</script>
VuexのmapActionsとpiniaのmapActionsは共存はできない?
どちらかのmapActionsを import時に as 別名にしてあげると同時に実行することができる。
piniaのコードを定義する
単純にuser情報を格納してfetchUserで取り出すコード
import { defineStore } from 'pinia'
export const useUsersStore = defineStore('users', {
state: () => ({
user: {}
}),
getters: {
getUser: ({ user }) => user
},
actions: {
async fetchUser() {
try {
console.log('Options API mounted')
const res = await fetch('https://jsonplaceholder.typicode.com/users/1')
.then((response) => response.json())
.then((data) => data)
this.user = JSON.parse(JSON.stringify(res))
} catch (e) {
console.error(e)
}
}
}
})
Option APIで定義してあるmountedはsetupよりも前に実行される感じっぽい。
そのため、mounted実行時はPiniaのStateはundefinedだった。
<script>
import { onMounted } from 'vue'
import { useCounterStore } from '@/stores/counter'
import { useUsersStore } from '@/stores/users'
export default {
setup() {
const counterStore = useCounterStore()
const usersStore = useUsersStore()
onMounted(async () => {
await usersStore.fetchUser()
counterStore.increment()
console.log('mounted')
console.log(counterStore.count)
console.log(usersStore.user.name)
})
return {
message: 'Hello world!',
counterStore,
usersStore
}
},
mounted() {
this.usersStore.fetchUser()
console.log(this.usersStore.user?.name)
if (this.usersStore.user.name === 'Leanne Graham') return // ここの処理が通らない
console.log('ある場合')
}
}
</script>
<template>
<h1 class="text-3xl font-bold underline">Hello world!</h1>
<p>{{ message }}</p>
</template>
このスクラップは5ヶ月前にクローズされました