この記事をおすすめしたい人
- 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からお届けしました!
Nuxt.js v3の目次
- 第1回 インストール方法とかフォルダ構成の違いとか
- 第2回 nuxt.config.jsの書き方の違い
- 第3回 注意が必要そうなモジュール
- 第4回 コンポーネントのscriptの書き方がめっちゃ変わった(このページ)
- 第5回 trailingSlashに手動で対応
- 第6回 injectの代用品を3つ紹介
- 第7回 v-forとv-ifの併用の代替案
- 第8回 defineNuxtComponentは救世主!
- 第9回 composablesがめっちゃ強いかもしれない
- 第10回 手動でAMPに対応する
- 第11回 フック一覧を簡単に調べた
- 第12回 axiosの代用品(useFetch、$fetch、useAsyncData)