Vue3の算出プロパティについて調べてみた
Vue 3の算出プロパティ(Computed Properties)は、コンポーネント内のリアクティブなデータに基づいて値を動的に計算するための機能です。テンプレート内の複雑なロジックをシンプルにし、コードの見通しを良くするために非常に役立ちます。
算出プロパティとは? 🤔
一言で言うと、「他のデータから派生するデータ」を定義するためのものです。例えば、firstName
と lastName
というデータがあったときに、それらを組み合わせて fullName
というデータを表示したい場合などに使います。
最大の特徴はキャッシュ機能です。算出プロパティが依存している元のデータ(例:firstName
)が変更された場合にのみ再計算されます。元のデータに変更がなければ、何度アクセスしてもキャッシュされた結果を返すため、パフォーマンスが向上します。
なぜ算出プロパティを使うのか?
-
テンプレートの可読性向上: テンプレート内に複雑な式を書く必要がなくなり、コードがスッキリします。
<div>{{ author.books.length > 0 ? 'Yes' : 'No' }}</div> <div>{{ hasPublishedBooks }}</div>
- パフォーマンス: 前述のキャッシュ機能により、不要な計算処理を避けることができます。メソッド呼び出しと比較すると、この違いが顕著になります。
基本的な使い方
Vue 3では、主にComposition APIとOptions APIの2つの書き方があります。
<script setup>
)
Composition API (Composition APIでは、computed
関数を vue
からインポートして使用します。
<script setup>
import { ref, computed } from 'vue'
// リアクティブなデータ
const price = ref(100)
const quantity = ref(2)
// 算出プロパティを定義
const totalPrice = computed(() => {
// priceかquantityが変更されると、この計算が自動的に再実行される
return price.value * quantity.value
})
const changeQuantity = () => {
quantity.value++
}
</script>
<template>
<div>
<p>単価: {{ price }}円</p>
<p>数量: {{ quantity }}個</p>
<p>合計金額: {{ totalPrice }}円</p>
<button @click="changeQuantity">数量を増やす</button>
</div>
</template>
ポイント:
-
computed
はゲッター関数を引数に取ります。 - 返り値は読み取り専用のrefオブジェクトです。値にアクセスするには
.value
を使いますが、テンプレート内では自動的に展開されるため不要です。
Options API
Options APIでは、コンポーネントの computed
オプション内に算出プロパティを定義します。
<script>
export default {
data() {
return {
firstName: 'Taro',
lastName: 'Yamada'
}
},
computed: {
// 算出プロパティ 'fullName'
fullName() {
// this経由でデータにアクセス
return this.firstName + ' ' + this.lastName
}
}
}
</script>
<template>
<p>フルネーム: {{ fullName }}</p>
</template>
ポイント:
-
computed
オプション内にメソッドとして定義します。 -
this
を使ってコンポーネントのdata
にアクセスします。 - テンプレート内では通常のプロパティのように
{ { fullName } }
の形で使えます。
算出プロパティ vs メソッド ⚖️
同じことをメソッドでも実現できますが、大きな違いはキャッシュの有無です。
<script setup>
import { ref, computed } from 'vue'
const count = ref(0)
// 算出プロパティ(依存するcountが変わらない限り再計算されない)
const computedValue = computed(() => {
console.log('Computed is calculated!')
return count.value + 1
})
// メソッド(呼び出されるたびに実行される)
const methodValue = () => {
console.log('Method is called!')
return count.value + 1
}
</script>
この例で、テンプレート内で computedValue
を複数回呼び出しても、コンソールログは一度しか表示されません。しかし、methodValue()
を複数回呼び出すと、その都度ログが表示されます。
算出プロパティ (computed) | メソッド (methods) | |
---|---|---|
キャッシュ | あり (依存データ変更時のみ再計算) | なし (呼び出すたびに実行) |
使い方 | データプロパティのように扱う | 関数として () をつけて呼び出す |
引数 | 取れない | 取れる |
適した場面 | リアクティブなデータに基づく値の計算 | イベント発火時の処理、引数が必要な計算 |
書き込み可能な算出プロパティ
通常、算出プロパティは読み取り専用ですが、get
と set
を提供することで書き込み可能にすることもできます。
例えば、fullName
を変更したら firstName
と lastName
も更新されるように実装できます。
<script setup>
import { ref, computed } from 'vue'
const firstName = ref('Taro')
const lastName = ref('Yamada')
const fullName = computed({
// ゲッター (値を取得するときに呼ばれる)
get() {
return firstName.value + ' ' + lastName.value
},
// セッター (新しい値を代入するときに呼ばれる)
set(newValue) {
const names = newValue.split(' ')
firstName.value = names[0]
lastName.value = names[1] || '' // 空白以降がない場合のエラー防止
}
})
// fullNameに値を代入すると、セッターが呼ばれてfirstNameとlastNameが更新される
fullName.value = 'Hanako Suzuki'
</script>
<template>
<p>First Name: {{ firstName }}</p> <p>Last Name: {{ lastName }}</p> </template>
この機能は、双方向バインディング(v-model
)を算出プロパティで使いたい場合などに便利です。
まとめ
Vue3の算出プロパティは、リアクティブなデータから派生する値を効率的に計算するための強力な機能です。
主なポイント:
- キャッシュ機能により、依存データが変更されない限り再計算されない
- テンプレートの可読性が向上し、複雑なロジックをシンプルに表現できる
- Composition APIとOptions APIの両方で使用可能
- 書き込み可能な算出プロパティも作成可能
使い分けの基準:
- リアクティブなデータに基づく値の計算 → 算出プロパティ
- イベント発火時の処理や引数が必要な計算 → メソッド
算出プロパティを適切に使いこなすことで、Vueアプリケーションのパフォーマンスと保守性を大幅に向上させることができます。
Discussion