【Nuxt3】script(Options API)とscript setup(Composition API)の書き方比較

シェアする:

この記事をおすすめしたい人

  • Nuxt3を始めようとしている人
  • script setupが意味不明な人
  • つまりオレ

Nuxt v3の調査、script setup編です。

コンポーネントのscriptだった部分が「script setup」という書き方に代わりました。 Vue側のアップデートに伴うもので、前者をOptions API、後者をComposition APIと呼ぶようです。

内部の構造に至ってはもはや別物。 なんでこんな書き方を推奨するようになったのか、Vue公式がQ&Aが出ていました。

僕にはほとんど理解できなかったわけですが…。

そんな人向けに従来仕様にかなり近いdefineNuxtComponentというのも用意されているみたいで、Composition APIは必須ではないみたい。

まぁ、みなさんの予想通り、僕は今defineNuxtComponentの方で書いていてscript setupの方は使っていないんですが、一応調べた範囲を可能な限りメモしておこうと思います。

僕はココに戻ってこれるんだろうか…。

囲い方がそもそも変わった

v2ではこんな↓風に書いていたのが、


<script>

</script>

v3ではこんな↓書き方が推奨されています。


<script setup lang="ts">

</script>

TypeScript推奨になったのでlangにtsが指定されていて、script setupはComposition APIの書き方です。

一応、従来通りのscript(setupなしの方)とかJavaScriptでも使えるみたいで、scriptとscript setupの併用も可能だとか。 ただし、JavaScriptを使うのかTypeScriptを使うのかは合わせないといけないみたい。

head

headはHTMLのheadタグに項目を追加したり上書きしたりする項目です。 v2ではこんな↓感じのコードでした。


export default {
  head () {
    return {
      title: 'ここにタイトルを書く',
    }
  }
}

これがv3ではuseHeadで定義するようです。

コードはこんな↓感じになります。


useHead({
  title: 'ここにタイトルを書く',
})

data

dataはコンポーネント内で使い回す変数を定義する部分です。 v2ではこんな↓コードでした。


data() {
  return {
    key: value,
  }
},

v3ではこう↓なりました。


const key = value

たったこれだけ!?

computed

computedというのは計算付き変数とでも呼べばいいのか、何か処理をさせて一定の値を返す.NETとかだとプロパティみたいに呼んでたやつだと思います。 関数とは違って引数は持たず、中身が変化しない限り1回しか計算されないとかそんなんだったはず。

v2ではこんな↓コード。


computed: {
  key() {
    return value
  },
},

v3ではこう↓なりました。


const key = computed(() => {
  return value
})

methods

関数ですね。 v2ではこんな↓コード。


methods: {
  key(value) {
    return value+1
  },
},

v3ではこうなりました。


const key = (value) => {
  return value+1
}

TypeScript式にやると型指定を追加した方がいいみたいですが、上のコードでもとりあえず通りました。

props

親コンポーネントから引数を受け取るpropsはv2ではこんな↓コード。


props: [
  'key',
],

v3ではこう↓なりました。


const props = defineProps([
  'key',
])

mounted

mountedってコンポーネントのインスタンスが作り終わって最後に実行されるイメージで、そのタイミングでしか調節できない変数の初期化とかそういうのに使ってたからscript setup式だとそもそも必要ないかなーと思ったんですが一応onMountedというのがあるみたいです。


onMounted(() => {
  console.log('onMounted-test')
})

この書き方しないといけないmountedをたぶんしたことないので、出会ったら追記します。

asyncData

asyncDataは、mountedと似ていますがもっと早い段階で実行される処理で、インスタンスが出来る前にAPIからページ情報を取得しておいて準備する、みたいなイメージです。

僕が作ったプロジェクトではAPIをだいたいローカルJSONにすることでasyncDataを使わなくなっていったのでなんともですが、useAsyncDataという仕組みがNuxt3にはあるようです。


const { data, pending, error, refresh } = await useAsyncData(
  'mountains',
  () => $fetch('https://api.nuxtjs.dev/mountains')
)

残ってるasyncDataがあったと思うのでそのプロジェクトを移植する際に追記します。

その他もろもろ

その他…と言ってもまだまだ色々ありそうですが、nameやlayoutなどの項目はdefinePageMetaというものを使うようです。


definePageMeta({
  layout: 'default'
})

何がここで設定できるのかはdefinePageMetaに一覧があります。

変化する変数は特殊な書き方が必要になった

v2の頃はこんな↓風に書くと「key」という変数に対する変化をtemplate内でもキャッチすることができました。


data() {
  return {
    flag: true,
  }
},

Nuxt3式だとこう↓。


const flag = true

どうもこれができなくなったっぽくて、script内では値が変わると反映されてるんですが、template内だと反映されてないようでした。 従来通り反映させるにはリアクティビティというのを考慮しないといけないようです。

んでこれが、こんな↓感じで初期化するみたいです。


const flag = ref(true)

こうすることでtemplate側ではそのまま変化をキャッチできるようになりました。

ただ、script内での扱いが別で、こんな↓風にvalueをつけないと中身にアクセスできないみたいです。


flag.value = false

分かれば単純ですが、すげー時間かかりました。 ただこれ、これで処理するとi9-9900kのPCでかくつくくらい重くなったんですよね。 大丈夫なんか。

この書き方の不便な点

いや、これ、どうなん?

検索するとめちゃくちゃ喜んでる人がいるみたいなので、たぶん僕の理解できないメリットがあるんだと思うんですが、

  • 上から順番に書いていくので宣言済みのものし扱えない
  • ブロックの範囲がないので、何をどこに書いているか分かりにくい
  • 変数の扱いがややこしい

というのがあって「今の僕」にはあまりメリットが感じられませんでした。

Nuxtやってる人はみんなすげー人が多い印象なのでこう感じる方が希なのかもですが、そういう人向けにv2と似た感じで書けるdefineNuxtComponentという記載方法がv3でも可能なようです。

今後、Composition APIのメリットを理解することになるとは思うんですが、どこに何を書いているか分からないというデメリットはずっと付いて回ると思うので、どうなんですかね。 NuxtさんはdefineNuxtComponentのサポート継続を切に願います。

現状感じているメリットとしては、defineNuxtComponentだとheadの呼び出しタイミングが早すぎて、コンポーネント内の変数やら関数にアクセスしにくくてですね。 headだけはuseHeadを使ってComposition APIを使う方が便利な局面がありそう。 使用言語(JavaScriptかTypeScriptか)が統一されていれば、script setup(Composition API)もscript(Options API)の併記が可能です。

以上、WordPressからお届けしました!

シェアする: