📘

Vue3の算出プロパティについて調べてみた

に公開

Vue 3の算出プロパティ(Computed Properties)は、コンポーネント内のリアクティブなデータに基づいて値を動的に計算するための機能です。テンプレート内の複雑なロジックをシンプルにし、コードの見通しを良くするために非常に役立ちます。


算出プロパティとは? 🤔

一言で言うと、「他のデータから派生するデータ」を定義するためのものです。例えば、firstNamelastName というデータがあったときに、それらを組み合わせて fullName というデータを表示したい場合などに使います。

最大の特徴はキャッシュ機能です。算出プロパティが依存している元のデータ(例:firstName)が変更された場合にのみ再計算されます。元のデータに変更がなければ、何度アクセスしてもキャッシュされた結果を返すため、パフォーマンスが向上します。

なぜ算出プロパティを使うのか?

  • テンプレートの可読性向上: テンプレート内に複雑な式を書く必要がなくなり、コードがスッキリします。
    <div>{{ author.books.length > 0 ? 'Yes' : 'No' }}</div>
    
    <div>{{ hasPublishedBooks }}</div>
    
  • パフォーマンス: 前述のキャッシュ機能により、不要な計算処理を避けることができます。メソッド呼び出しと比較すると、この違いが顕著になります。

基本的な使い方

Vue 3では、主にComposition APIとOptions APIの2つの書き方があります。

Composition API (<script setup>)

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)
キャッシュ あり (依存データ変更時のみ再計算) なし (呼び出すたびに実行)
使い方 データプロパティのように扱う 関数として () をつけて呼び出す
引数 取れない 取れる
適した場面 リアクティブなデータに基づく値の計算 イベント発火時の処理、引数が必要な計算

書き込み可能な算出プロパティ

通常、算出プロパティは読み取り専用ですが、getset を提供することで書き込み可能にすることもできます。

例えば、fullName を変更したら firstNamelastName も更新されるように実装できます。

<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 APIOptions APIの両方で使用可能
  • 書き込み可能な算出プロパティも作成可能

使い分けの基準:

  • リアクティブなデータに基づく値の計算 → 算出プロパティ
  • イベント発火時の処理や引数が必要な計算 → メソッド

算出プロパティを適切に使いこなすことで、Vueアプリケーションのパフォーマンスと保守性を大幅に向上させることができます。

GitHubで編集を提案

Discussion