Vue2からVue3への移行調査

社内のプロジェクトで「Vue2 × Class Component」での開発から「Vue3 × Composition API」へ移行する可能性を探りたい、という話になり、以下3点について調査したので、まとめてみました。

- Vue3へ移行するメリット
- 必要となる移行作業
- Class ComponentからComposition APIに書き換えるべきか

## Vue3へ移行するメリット

- Vue3はTypeScriptで開発されているため、Vuexなどのライブラリ含め型推論が効きやすい
- 当然、サポートが切れるのはVue2よりも後になる
- Composition APIで書くことにより、ロジックを1箇所にまとめやすく、また単体テストが書きやすい
※Composition API自体はVue2のプラグインでも使用可能ですが。。

など...

参考になった記事をいくつか貼っておきます。

https://www.ragate.co.jp/blog/articles/8232

https://www.ragate.co.jp/blog/articles/9888

https://www.ragate.co.jp/blog/articles/8703

 

## 必要となる移行作業

表にまとめると、このようになりました。
移行コストは私のプロジェクトでの話になる旨、ご了承ください。

| 内容                      | 移行コスト | 対応必須なら○ | 備考                                                                                                                                                                                                                                  | 公式ドキュメント                                               | 
| ------------------------- | ---------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | 
| Composition APIへ書き換え | 大         |              | Class ComponentとComposition APIは混在可能なため、段階的に移行可能。                                                                                                                                                                    |         https://v3.ja.vuejs.org/api/composition-api.html                                                       | 
| その他Vue3の変更点        | 中         | ◯           | 移行ビルド「@vue/compat」を使用すればVue2とVue3の混在が可能で、段階的に移行出来る。                                                                                      | https://v3.ja.vuejs.org/guide/migration/migration-build.html   | 
| Vuetify3へ移行            | ？         | ◯           | ベータ版とはいえ、対応はほぼ完了している。<br>ドキュメントが完成しておらず、移行コストは不明。                                                                                                                                            | https://github.com/vuetifyjs/vuetify/issues/14984              | 
| Vue Router4へ移行         | 小         | ◯           | そこそこ変更はあるものの、移行を躊躇するほどでは無い。                                                                                                                                                                                  | https://router.vuejs.org/guide/migration/index.html            | 
| VueX4へ移行               | 小         | ◯           | 破壊的変更はほぼ無く、移行は一番簡単かも。<br>Piniaへの移行も有り。（※1）                                                                                                                                                                                              | https://vuex.vuejs.org/ja/guide/migrating-to-4-0-from-3-x.html | 
| その他ライブラリの移行    | 中         | ◯           | Vueに依存するライブラリにはVue3未対応のライブラリも結構あるため、それらを代替ライブラリに置き換える必要がある。<br>またVuetify3の利用にwebpack5以上が必須のため、バージョン4以下の場合は周辺ライブラリ含めバージョンアップが必要。 |                                                                | 
 
:::note info
※1　Piniaとは
https://pinia.vuejs.org/
- Vueで新しく推奨されている状態管理ライブラリ
- TypeScriptのフルサポート（Vuex4と比較してどれほど優れているかは不明）
- 一つのglobal storeを管理するVuexと異なり、storeが複数に分かれている（必要なstoreのみ呼び出して使用可能だが、呼び出すstoreが増えると少し複雑になりそう）
:::

## Class ComponentからComposition APIに書き換えるべきか

前提として、Vueには大きく分けて3つの書き方があるかと思います。

https://v3.ja.vuejs.org/api/composition-api.html

1. Options API（Vue2のベーシックな書き方） 
2. Class Component（Vue2 × TypeScriptでよく使われた書き方）
3. Composition API（Vue3で推奨される書き方。Reactの関数コンポーネントの書き方に近い）



Vue3へ移行後も引き続きClass Componentを使用可能だが、以下の理由からComposition APIに書き換えた方が良さそう。

- Class Componentを非推奨にする案がissueに上がっており、Evan Youさん（Vueの第一人者）も推奨しない旨の発言をしている。
    https://github.com/vuejs/core/issues/4744#issuecomment-937369062
- 推奨されているComposition APIではTypeScriptとの相性も改善され、今後の主流になりそう
- Class Component開発リポジトリは2020年9月を最後に更新が止まっている。
- Class Componentで使用する「vue-property-decorator」も2020年4月で更新が止まっている。


以上です。
私のプロジェクトでは、結局Reactに移行することになりました。笑