こんにちは。新卒2年目ソフトウェアエンジニアのほっしーです。
Vue.jsの勉強のために個人で作ったWebアプリをVue2からVue3へ移行しました。その際に悩んだ・行き詰まった点をまとめました。「refとreactiveどっちを使えばいいのか?」といった情報は調べれば出てくると思いますが、悩んだ・行き詰まったポイントについてはなかなか出回っていなかったので、同じ悩みを持つ方に向けて書き残しておきます。
主な作業内容
今回、Vue2からVue3へ移行した際に以下の2つの作業を行いました。
・パッケージのバージョンアップ・入れ替え
・Vue3で使えなくなる書き方の修正
勉強のためにOptions APIからComposition APIへ書き換えた部分もありますが、こちらの書き換えはなくても問題ありません。
どのパッケージをインストールするか
まずはパッケージのバージョンアップ・入れ替えを行いました。念の為記載しておくと、Vue2からVue3へ移行する際はパッケージのバージョンアップ・入れ替えは必須です。Vue2でコードを書いていた際は主に以下のパッケージを使用していました。
"vite": "^2.7.2", "vue": "^2.6.10", "vue-router": "^3.5.2", "vite-plugin-vue2": "^1.4.0",
Vue関連のパッケージは調べたらすぐに見つかったので特に悩むことはなかったのですが、vite周りについては調べても意外と良さげな情報が出て来ず試行錯誤しました。今のところは以下のパッケージで問題なく動作しています。
"vite": "^3.2.2", "vue": "^3.2.47", "vue-router": "^4.1.6", "@vitejs/plugin-vue": "^3.0.1",
Composition APIを使う際の雛形
まずはmixinで書かれていたファイルをComposition APIの形式で書き換えました。Vue3でもmixinは使えるのですが、推奨はされていないため良い機会なので丸々作り直しました。
公式のドキュメントも含めてネット上には様々な情報が転がっていますが、
・setup()
と<script setup>
どちらを使っているのか
・ファイルの拡張子は何なのか
・何をexportしてどのようにimportするのか
などサンプルごとにバラバラで読み解くのにかなり時間がかかりました。
簡略化はしていますが最終的には以下のような書き方に落ち着きました。
import {reactive} from 'vue' const setUser = (currentLoginUser) => { Object.assign(loginUserStore, {...currentLoginUser}) } export const loginUserStore = reactive({ email: '', nickName: '', uid: '', photoURL: '', setUser, })
ファイル名はLoginUserStore.jsで以下のように呼び出します。
import {computed, inject, ref} from 'vue' const loginUserStore = inject('loginUserStore')
想定外の行で発生したエラー
BoardCardDisplay.vueはOptions APIで書かれたファイルです。Vue3でもOptions APIは使えるので特に書き換えるつもりはなかったのですが、ビルド時に以下のエラーが発生してしまいました。
transforming (480) resources/js/components/board/BoardCardDisplay.vueError when using sourcemap for reporting an error: Can't resolve original location of error. ✓ 480 modules transformed. [commonjs] Unexpected token (Note that you need plugins to import files that are not JavaScript) file: /Users/中略/resources/js/components/board/BoardCardDisplay.vue:190:12
「エラーが出たらまずは検索」ということで調べてみましたが、それらしい情報は見つかりませんでした。そもそもBoardCardDisplay.vueは164行目までしかないため、完全にお手上げ状態でした。
エラーから原因が特定できない以上、地道にコード上の誤りを見つけるしかありません。<template>
タグ内を部分的にコメントアウトしながらエラーが発生する行を特定していきました。その結果、以下の行をコメントアウトした際にエラーが発生しなくなりました。
<p class="main" v-html=""></p>
なぜ今までエラーが発生していなかったのか未だに理由はわかりませんが、同じエラーに苦しむ人に向けて書き残しておくのでお役立てください。
感想
Vue3とComposition APIの雛形が出来上がるまでには1、2日ほどかかりましたが、一度出来上がってからは意外とサクサク作業が進みました。まだまだ状態管理周りの作り込みが甘いので、このままComposition APIで仕上げていくのかPiniaなどのライブラリを使用するか検討しようと思います。