Nuxt3のOption APIからComposition APIに移行する

Vue2 で使われていた Options API は、Vue3からできるようになったComposition API がでたことで直感的で分かりやすくなったことで、アップグレードのタイミングで移行したい人が多くいると思います。(Vue2でもComposition APIがつかえるみたいですが)

スクリーンショット 2025-04-14 1.37.12

ここでは移行するコツをご紹介していこうかなと思います。

Option APIとComposition APIの違い

Vue コンポーネントの記述スタイルを指します。 目的は同じですが、書き方・設計思想・拡張性に違いがあります。

# Option APIでの記述
<script lang="ts">
export default defineNuxtComponent({
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    }
  }
})
</script>
# Composition APIでの記述
<script lang="ts" setup>
import { ref } from 'vue';

const count = ref(0);
const increment = () => {
  count.value++;
};
</script>

<script setup>にて直接setupの中に記述していくのが特徴です。 dataref と対応する記述が変わってコンパイル時に変換されるらしいです。 併用も可能ですが、できればプロジェクト単位で統一したいですよね。

自動マイグレーションツールは公式でもなさそうなので、自作している人もいますけど完璧ではなさそうな気はしています。

https://github.com/vuejs/composition-api-converter

各メソッドの対比表

機能・項目 Option APIの定義 Composition APIの定義
データ (state) data() { return { count: 0 } } const count = ref(0)
メソッド methods: { increment() { ... } } const increment = () => { ... }
算出プロパティ computed: { double() { return ... } } const double = computed(() => ...)
ウォッチャー watch: { count(val) { ... } } watch(count, (val) => { ... })
ライフサイクル(作成) created() { ... } そのままsetupに記載(または onMounted)
ライフサイクル(マウント) mounted() { ... } onMounted(() => { ... })
ライフサイクル Option APIのライフサイクル Composition APIのライフサイクル
propsの定義 props: ['title'] defineProps<{ title: string }>()
emitsの定義 emits: ['submit'] defineEmits<() => void>()
テンプレートで使える変数 this.count 変数名そのまま(例:count
非同期データ取得(サーバーサイド) asyncData const { data } = await useAsyncData('key', fetcher)

単純置き換えだけでは不具合が起こる可能性があります。 Composition APIにすることで、コンポーザブルへのアクセスでエラーになったりもするので 例外処理などもしっかり確認していくといいでしょう。

参考: https://nuxt.com/docs/guide/concepts/auto-imports#vue-and-nuxt-composables

参考: https://nuxt.com/docs/api/composables/use-nuxt-app#runwithcontext

Nuxtインスタンスへのアクセス時にはrunWithContext()を使ったりするといいかなと思います。

const result = nuxtApp.runWithContext(() => functionWithContext())

まとめ

基本的にやれることは同じだと思っていますが、単純に置き換えるだけだと色々問題が起こるかなと思います。 自分も単純な置き換えだけでいけると思っていましたが、いざ変更すると色々と問題(エラー)も起こっていたので、しっかりと確認しつつ変更していきましょう。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です