Vue3では、従来のオプションAPIに加えて、Composition APIが導入されました。Composition APIでは、Vue2のcomputedプロパティに相当する機能を、computed
関数として提供しています。computed
関数は、状態の変化に応じて再評価されるリアクティブな値を作成することができます。
computed
関数の使い方
computed
関数は、2つの引数を取ります。
getter
関数:計算されたプロパティの値を返す関数です。setter
関数(オプション):計算されたプロパティの値が変更されたときに呼び出される関数です。変更を反映するための状態の更新をここで行います。
以下は、単純な例です。name
とage
という2つの状態を使って、fullName
という計算されたプロパティを作成します。
import { computed, reactive } from 'vue'
const state = reactive({
name: 'John',
age: 30
})
const fullName = computed(() => {
return `${state.name} (${state.age})`
})
fullName
は、state.name
とstate.age
が変更されるたびに再評価されます。
Composition APIでのcomputedの使い方
Composition APIを使用すると、setup
関数内でcomputed
関数を使用することができます。以下は、Composition APIを使用した例です。
import { computed, reactive, toRefs } from 'vue'
export default {
setup() {
const state = reactive({
name: 'John',
age: 30
})
const fullName = computed(() => {
return `${state.name} (${state.age})`
})
return {
...toRefs(state),
fullName
}
}
}
toRefs
関数を使用すると、state
オブジェクト内のプロパティがリアクティブな参照として公開されます。fullName
プロパティも同様に公開されます。これにより、テンプレート内でこれらの値に簡単にアクセスすることができます。
<template>
<div>
<p>Name: {{ name }}</p>
<p>Age: {{ age }}</p>
<p>Full name: {{ fullName }}</p>
</div>
</template>
computedプロパティとcomputed関数の違い
従来のオプションAPIでは、Vueコンポーネントでcomputed
プロパティを定義していました。Composition APIでは、代わりにcomputed
関数を使用します。computed
関数は、Vueコンポーネントのsetup
関数内で呼び出されます。以下は、オプションAPIとComposition APIでのcomputedの使用例です。
オプションAPI
export default {
data() {
return {
name: 'John',
age: 30
}
},
computed: {
fullName() {
return `${this.name} (${this.age})`
}
}
}
Composition API
import { computed, reactive, toRefs } from 'vue'
export default {
setup() {
const state = reactive({
name: 'John',
age: 30
})
const fullName = computed(() => {
return `${state.name} (${state.age})`
})
return {
...toRefs(state),
fullName
}
}
}
オプションAPIでは、computed
プロパティは、コンポーネントのオプションオブジェクト内に定義されます。Composition APIでは、computed
関数は、setup
関数内で定義されます。
computed関数のリアクティブな依存関係
computed関数は、参照するデータに基づいて自動的に再評価されます。この依存関係は、Vueによってトラッキングされ、必要に応じて再評価されます。以下は、リアクティブな状態の変更に応じてcomputedプロパティが自動的に更新される例です。
import { computed, reactive } from 'vue'
const state = reactive({
name: 'John',
age: 30
})
const fullName = computed(() => {
return `${state.name} (${state.age})`
})
console.log(fullName.value) // "John (30)"
state.age = 31
console.log(fullName.value) // "John (31)"
fullName
は、state.name
とstate.age
に依存しているため、state.age
が変更されると、自動的に再評価されます。
computed関数のキャッシュ
computed関数は、その結果をキャッシュし、同じ入力に対して複数回評価されないようにします。キャッシュされた値は、同じ参照が保持されるため、computed
関数の返り値はref
オブジェクトではなく、その値自体です。以下は、computed
関数のキャッシュの例です。
import { computed } from 'vue'
const count = ref(0)
const doubled = computed(() => {
console.log('computed!')
return count.value * 2
})
console.log(doubled.value) // 0
count.value = 1
console.log(doubled.value) // 2
computed
関数は、最初に呼び出されたときにキャッシュされ、以降の呼び出しでは、キャッシュされた値が返されます。上記の例では、最初の呼び出しではcomputed!
がコンソールにログされますが、2回目の呼び出しではログされません。
computed関数とwatch関数を組み合わせる
computed関数は、デフォルトではリアクティブな状態をすべて監視しますが、この振る舞いをカスタマイズすることもできます。computed
関数には、オプションとして、監視するリアクティブな状態を明示的に指定することができるwatch
オプションがあります。このオプションを指定することで、computed
関数の再評価をトリガーするリアクティブな状態を明示的に制御できます。以下は、watch
オプションを使用したcomputed関数の例です。
import { computed, reactive } from 'vue'
const state = reactive({
name: 'John',
age: 30
})
const fullName = computed(
() => {
console.log('computed!')
return `${state.name} (${state.age})`
},
{ watch: { age: true } }
)
console.log(fullName.value) // "John (30)"
state.name = 'Jane'
console.log(fullName.value) // "John (30)"
state.age = 31
console.log(fullName.value) // "Jane (31)"
上記の例では、watch
オプションが{ age: true }
に設定されており、fullName
はstate.age
に依存しています。したがって、state.age
の値が変更されると、fullName
は再評価されますが、state.name
の値が変更されても再評価されません。
まとめ
computed関数は、VueのComposition APIで、リアクティブな値を計算するために使用されます。computed関数は、自動的に再評価され、キャッシュされ、メモ化することができます。watch
オプションを使用することで、computed関数が再評価されるトリガーとなるリアクティブな状態を制御できます。