【vue】 computedで自動で再計算する
算術プロパティと呼ばれる機能です。data
が固定の値を出力するのに対し、computed
は計算した値を出力するというものです。書き方はmethod
と似ていますが、役目はそれと違います。
computedを利用した例
例えば、次の例を見てみましょう。
const app = Vue.createApp({ data() { return { shareId: "abcde", shareUrl: "https://example.com/" } }, mounted() { this.createShareUrl(); }, methods: { startShare() { this.shareId = "abcde"; // TODO: ランダムで変更する処理 this.createShareUrl(); }, changeShareId() { this.shareId = "bcdef"; // TODO: ランダムで変更する処理 this.createShareUrl(); }, stopShare() { this.shareId = ""; this.createShareUrl(); }, createShareUrl() { this.shareUrl = "https://example.com/?id=" + this.shareId; } } });
シェア用のURLを生成する機能を作っているようですが、何度もcreateShareUrl
を呼び出しています。その上、urlは表示以外で使うとは思えません。 (内部はidで管理のため)
こういった、特定の値が変わると自動で更新してほしい値は、その値に連動して自動的に表示が書き換わるのが理想ですよね。しかし表示だけだった場合にHTML側で連結したりするのは、ロジックをHTMLに書いていることになるのであまり良くありません。そこで、computedの出番です。
const app = Vue.createApp({ data() { return { shareId: "abcde", } }, computed: { shareUrl() { return "https://example.com/?id=" + this.shareId; } }, methods: { startShare() { this.shareId = "abcde"; }, changeShareId() { // ランダム文字列を生成 this.shareId = Math.random().toString(32).substring(2); }, stopShare() { this.shareId = ""; } } });
スッキリしました。computed
にメソッドが入っているのがわかります。
computedの特徴
- 利用している変数の値が変更されると, 自動的にcomputedも再計算される
- dataと同様の方法で値を取得できる
- 直接書き換えることは、追加実装しないとできない
this.shareUrl = "aaa"
のようなことはsetterを実装しないとできない
という特徴があります。なにかの値に応じて、計算した結果を表示したいときに便利です。
値を取得する
methods
とは違い、関数としてではなく、data
と同様に変数のように呼び出します。
const app = Vue.createApp({ data() { return { shareId: "abcde", } }, computed: { shareUrl() { return "https://example.com/?id=" + this.shareId; } } });
<p>{{ shareUrl }}</p>
See the Pen vue1 computed by Totori (@souki202) on CodePen.
vue内でも、普通の変数のように呼び出しますが、取得のみで代入はしません。
const app = Vue.createApp({ data() { return { shareId: "abcde", } }, computed: { shareUrl() { return "https://example.com/?id=" + this.shareId; } }, methods: { changeShareId() { this.shareId = Math.random().toString(32).substring(2); // computedのメソッドは変数のように呼び出す (この時点で更新済み) console.log(this.shareUrl); }, } });
setterも実装はできるのでsetできなくはないですが面倒です。methods
やwatch
が向いている場面がほとんどです。
リアクティブ性
上の動作例では、computed
に使用している変数が更新されると、自動で対応するcomputed
に設定したメソッドが動作し、HTML側の表示が更新されます。
つまり、値を更新した後にわざわざ更新する処理の呼び出しを書かなくてよいということです。
ここで、使用している値がリアクティブなものでない場合は、値が変わっていたとしても更新されません。
ここで該当するリアクティブなものとは、vueのdata
で設定した値が主です。
const app = Vue.createApp({ data() { return { shareId: "abcde", } }, computed: { date() { // new Date()の結果は時刻によって変わるが、リアクティブではないのでcomputed実行の条件を満たさない return new Date(); }, shareUrl() { // dataにいれたshareIdの値が更新されると、shareUrl()は実行される return "https://example.com/?id=" + this.shareId; } }, methods: { // ... } });
setterの実装
通常は値を取得するgetterのみですが、値をセットするsetterも作ることができます。
const app = Vue.createApp({ data() { return { firstName: "Taro", lastName: "Yamada" }; }, computed: { fullName: { get: function () { return `${this.firstName} ${this.lastName}`; }, set: function (v) { const names = v.split(" "); this.firstName = names[0]; this.lastName = names[names.length - 1]; } } } });
上のスクリプトの例では、fullName
に値を代入した際にfullName
のset
が呼ばれます。
つまり、vueでthis.fullName = "Hoge Fugaaa"
をしたり、
<input type="text" v-model="fullName">
で反映したりするとset
が実行されます。引数には代入しようとしている値が入ります。
これはJavascriptでよく見られるgetterとsetterの書き方です。
See the Pen vue computed setter by Totori (@souki202) on CodePen.
methodsとの違い
比較してみましょう. method
とcomputed
の主な違いは2点です.
computed | methods | |
---|---|---|
実行タイミング | 内部で利用している値が変更されたとき | 呼び出したとき |
呼び出し方 | dataと同じ | メソッド呼び出しと同じ |
つまり、普通にロジックを実装するならmethods
、利用する値が変更されたときに自動的に計算したい、かつ戻り値を使いたいならcomputed
を利用すると良いです。dataの代わりとして使えます。
利用する値が変更されたときに自動的にロジックを走らせたい、でも戻り値は不要という場合は、後で紹介するwatch
が適任です。
また、computed
は裏で結果がキャッシュされているため、余分な再計算が起こらないのもメリットです。
まとめ
computedは、中で使用する値が更新されると自動で再計算し、表示する値を更新できるものです。method
との違いを把握して使い分けられるようになりましょう。
似ているwatch
については下の記事にあります。
method
, computed
, watch
の使い分けは下の記事にあります。
