この記事は、ラクスパートナーズ AdventCalendar 2025の1日目の記事です。
(個人で25日連続投稿にチャレンジ中のカレンダーになります)
現場で、Vueのバージョンを2.6 → 2.7にアップグレードする作業をしたので、その際にやったことをメモしていきたいと思います。
(といっても、概ねは公式のアップグレードガイドに則って進めました)
Vue2.7の概要
Vue2.7はVue2系の最後のマイナーバージョンです。2023年末にサポートが終了したVue2と標準になったVue3の橋渡しとなるバージョンになっています。
Vue2.7には、Vue3の重要な機能の一部がバックポートされています。主な機能は以下です。
Comosition API
- コードの自由度が高くなり、関心事単位でコードをまとめることができる
- Option APIよりロジックを再利用しやすくなる
- data、methods、computedなどを行ったり来たりせずに済むので、コードを読みやすくなる
- TypeScriptとの親和性が高い
- 変数や関数をそのまま書けるのと型推論が強化されたため
- thisが使えなくなる点には注意
<script setup>
- setup)でロジックを描く必要がなくなる
- export defaultやreturnを書かずに済み、コードを短くできる
- setup()を使うよりもパフォーマンスが上がる
- 型推論が早くなる
CSS v-bind
- styleタグ内でv-bindできる
- これによりCSSを動的に適用できる
もちろんVue2.7では対応していない機能もあるので、注意が必要です。
詳細はこちら
また、Vue.js公式でVue2系を使い続ける場合は2.7に上げることを推奨する旨のメッセージが書いてありました。Vue3への移行が難しい場合は、せめて2.7には上げておいた方がよさそうですね。
Vue 2.7 will also be the maintained release before EOL hits, so if you intend to stay on Vue 2, you should at least upgrade to Vue 2.7.
引用元
ライブラリのアップグレード
今回はVue CLIを導入している想定で書きます。
- @vue/cli-〇〇系のライブラリを以下のバージョンにアップグレードします。
- v4の場合:~4.5.18
- v5の場合:~5.0.6
- vueを^2.7.0にアップグレードします。また、vue-template-compilerはvue2.7から不要になったので削除します.
(@vue/test-utilsを使用している場合はvue-template-compilerが必要なので注意) - package-lock.jsonで以下のライブラリがインストールされている場合、以下のバージョンを満たしているか確認します。
- vue-loader: ^15.10.0
- vue-demi: ^0.13.1
- 元から@vue/composition-apiを使用していた場合は、import分の参照先をvueに更新します(バックポートで提供されているため)
- <script setup>を使用する場合は、eslint-plugin-vueを最新バージョン(v9)に更新します(そうしないとLint関連のエラーが出るため)
- VueRouterをvue2.7に対応している3.6.0以上に上げます。
参考:https://zenn.dev/monica/articles/7d3417c07b6cf4 - PostCSS7を使用している場合は、関連するプラグインをPostCSS8に対応したバージョンにあげます
- Vue2.7のSFC(単一コンポーネント)コンパイラはPostCSS8を使用しているため
コードで修正したところ
scriptタグを<script setup>にする
Composition APIへ書き換えられるようにします。
Vuexのstoreを参照できるようexport
Composition APIにしたことで、this.$storeでstoreを参照できなくなったので、Vuexのstoreをexportします
const store = new Vuex.Store({
state: {},
getters: {},
mutations: {},
actions: {}
})
// 外部ファイルで参照できるようにする
export const useStore = () => store;
import { useStore } from './store';
const store = useStore();
VueRouterはComposablesに置き換える
VueRouterも同様にthis.$routerの形式で参照できなくなったので、以下のように修正します。
import { useRouter, useRoute } from 'vue-router/composables';
const router = useRouter();
const route = useRoute();
// トップページに遷移
router.push('/');
// 現在のパスを取得
console.log(route.path)
package.jsonにESLintの設置を追加
コンポーネント名に単一の単語を使っている場合は
「コンポーネントは複数単語で命名してください」
という旨のエラーが発生します。
コンポーネント名を変えずにエラーを抑えたい場合は、package.jsonに以下の設定を追加します。
"eslintConfig": {
"rules": {
"vue/multi-word-component-names": "off"
}
}
コンポーネントファイルの先頭に以下のコメントを追加することでもエラーを抑えることができますが、package.json側で一括で設定した方が楽です。
<!-- eslint-disable vue/multi-word-component-names -->
props、emitsをdefinePropsとdefineEmitsに書き換える
const props = defineProps({
name: {
type: String,
required: true
},
age: {
type: Number,
required: true
},
})
const emit = defineEmits(['click'])
dataプロパティ内の変数をref()に置き換える
Option APIでdataプロパティ内に定義していた変数をref()で宣言します。
import { ref } from 'vue';
const name = ref('');
console.log(name.value)
Vue2.7でもreactive()は使えますが、reactive()には
- プリミティブな値を保持できない
- オブジェクト全体を更新できない
といった制限があります。
そういった理由からVue公式がreactive()よりref()の使用を推奨していたので、こちらの方がよさそうです。
参考
computed()を修正する
Option APIのcomputedプロパティをCompositin APIの書き方に修正します。
import { computed } from 'vue';
import { useRouter } from 'vue-router-composables';
const route = useRoute();
const isHome = computed(() => route.path === '/');
this.$nextTickをnextTickに修正
nextTickもthis経由では参照できなくなるので修正します。
import { nextTixk } from 'vue';
nextTick(() => {
// DOM更新後の処理
})
Vueインスタンスを取得したい場合はgetCurrentInstance()を使う
現在のコンポーネントインスタンスにアクセスしたいときは、getCurrentInstance()で取得できます。
import { getCurrentInstance } from 'vue';
const { proxy } = getCurrentInstance();
私の場合は、特定のライブラリの関数をどうしても参照することができなかったため、getCurrentInstance()経由で参照しました。
ただ、最終手段として考えた方がよさそうです。
ライフサイクルフックを修正する
ライフサイクルフックもVue3のものに書き換える必要があります。
特に、veforecreateとcreatedは、<script setup>直下に書く形となったので注意が必要です。
以下はmountedの例です。
import { onMounted } from 'vue';
// beforecreate、createdの処理はここ
onMounted(() => {
// コンポーネントがマウントされた後の処理
});
あとがき
以上が、私がVue2.7へアップグレードした際にやったこととなります。
今回の作業を通して、Vue2とVue3両方の特徴を学ぶことができて、たいへん勉強になりました。
現在Vue3への移行作業も進めておりますので、また移行完了した際には記事にしたいと思います。
ここまで読んでいただきありがとうございました。