こんにちは、かつコーチです。
前回は v-for ・ v-if を使ったリスト表示と条件分岐を解説しました。
今回からは一歩進んで、Vue.jsの現在の主流である「Composition API」を扱っていきます。
その入り口となるのが <script setup> という書き方です。
「見た目は今までと違うのに、なぜかシンプルになる」その理由を、順を追って理解していきましょう。
Composition APIとは?
Options APIとの違い
Vue.jsには大きく分けて2つの書き方があります。
Options API は data ・ methods ・ computed のように、役割ごとにオプションを分けて書くスタイルです。
一方 Composition API は、関連するデータと処理を1つの関数の中にまとめて書けるスタイルです。
コンポーネントが小さいうちはどちらでも大差ありませんが、機能が増えて複雑になるほどComposition APIの恩恵が大きくなります。
「同じ機能に関するコードが、あちこちのオプションに分散せず1箇所にまとまる」というのが最大のメリットです。
なぜscript setupを使うのか
Composition APIには setup() 関数を使う書き方もありますが、実務では <script setup> を使うのが今の主流です。
理由はシンプルで、記述量が圧倒的に少なくて済むからです。
setup() の中で return していた値を、<script setup> ではそのままテンプレートで使えます。
私も最初は「なぜ2つも書き方があるのか」と混乱しましたが、<script setup> は setup() の糖衣構文(シンタックスシュガー)と理解すると腑に落ちました。
これから新しくVueのコードを書くなら、<script setup> 一択と考えて問題ありません。
script setupの基本の書き方
refでデータを定義する
まずはシンプルな例を見てみましょう。
<script setup lang="ts">
import { ref } from 'vue'
const count = ref<number>(0)
const increment = (): void => {
count.value++
}
</script>
<template>
<p>カウント: {{ count }}</p>
<button @click="increment">+1</button>
</template>
ref で定義した count は、テンプレート側では {{ count }} とそのまま書くだけで表示できます。
<script setup> を使うと、data や methods にまとめる作業がなくなり、宣言した変数や関数がそのままテンプレートで使えるようになります。
reactiveでオブジェクトを扱う
複数のプロパティをまとめて管理したい場合は reactive を使います。
<script setup lang="ts">
import { reactive } from 'vue'
interface User {
name: string
age: number
}
const user = reactive<User>({
name: 'かつコーチ',
age: 30,
})
const birthday = (): void => {
user.age++
}
</script>
<template>
<p>{{ user.name }}さんは{{ user.age }}歳です</p>
<button @click="birthday">誕生日を迎える</button>
</template>
ref は主に単一の値、reactive は主にオブジェクトや配列に使う、とざっくり使い分けておくと迷いません。
TypeScriptと組み合わせる場合は、interface で型を先に定義しておくと、後からプロパティの型ミスにすぐ気づけます。
つまずきやすいポイント:refの.value忘れ
スクリプト内では.valueが必要
ref を使い始めた頃、私が何度もハマったのが .value の付け忘れです。
❌ Before:スクリプト内で.valueを付け忘れる
<script setup lang="ts">
import { ref } from 'vue'
const count = ref<number>(0)
const increment = (): void => {
count++ // エラー: countはref型のオブジェクトなので直接演算できない
}
</script>
ref で作った変数は、実は中身が直接入っているわけではなく、.value というプロパティに値が包まれた状態になっています。
このコードは、TypeScriptを使っていれば「演算子がRefオブジェクトに適用できない」という趣旨のエラーで教えてくれますが、素のJavaScriptだと気づきにくいので要注意です。
✅ After:スクリプト内では.valueを付けてアクセスする
<script setup lang="ts">
import { ref } from 'vue'
const count = ref<number>(0)
const increment = (): void => {
count.value++ // .valueを付けて中身にアクセスする
}
</script>
ちなみにテンプレート側では .value を書く必要はありません。
Vueがテンプレートをコンパイルする際に、自動的に .value を補ってくれる仕組みになっているためです。
「スクリプト内は.valueが必要、テンプレート内は不要」というルールをセットで覚えておきましょう。
応用:computedやpropsとの組み合わせ
この先の学習の見通し
<script setup> の基本を押さえたら、次は computed で算出プロパティを扱ったり、watch でデータの変化を監視したりと、応用の幅が一気に広がります。
さらに親子間でデータをやり取りする props ・ emit も、すべて <script setup> の中で完結して書けます。
まずは今回紹介した ref と reactive の使い分け、そして .value のルールをしっかり体に染み込ませておくと、この先の内容がぐっと理解しやすくなります。
まとめ
この記事のポイント
<script setup>はComposition APIを簡潔に書くための構文で、今の主流の書き方refは単一の値、reactiveはオブジェクトや配列を扱うのに向いている- スクリプト内では
.valueが必要、テンプレート内では不要という違いに注意する - TypeScriptと組み合わせると、型定義によって早い段階でミスに気づける
次に読むべき記事
次回は、データの変化を監視する watch と watchEffect の使い分けを解説します。
→ 次の記事:watchとwatchEffectの使い分け