- Part1~Nuxt.js概要まとめ編~はこちら
- Part2~チュートリアル実践編~はこちら
- Part3~小ネタ:Vuexとは?編~はこちら
- Part5~小ネタ:propsとdataの違い編~はこちら
はじめに
お久しぶり?です、筆者です。
前回は、Part2で実施したチュートリアル実践中に気になり深掘りしたこと3つ:
- Vuexとは?
- computedとmethodsの違い
- propsとdataの違い
…のうち1番目の「Vuexとは?」についてまとめてみました。
今回では、2番目となる「computedとmethodsの違い」についてを見ていこうかなと。
※結構ボリューム多くまとめちゃったので、ご了承をば…。
それでは行きましょう。
computedとmethodsの違い
公式記事によると、computedは正式には「算出メソッド」、methodsはそのまんま「メソッド」という意だそうで。
jp.vuejs.org
computedとmethodsの違いは、「リアクティブな依存関係にもとづきキャッシュしてくれる」こと。
※リアクティブという単語の意味については、こちらの記事が分かりやすかったです:
リアクティブプログラミングへの理解がイマイチだったのでまとめてみた - UUUM攻殻機動隊(エンジニアブログ)
公式記事の例をまんま持ってきますが…例えば下記の様なコードがあった際:
<p>Reversed message: "{{ reverseMessage() }}"</p>
// コンポーネント内 computed: { reverseMessage: function () { return this.message.split('').reverse().join('') } }
上記の様にcomputedでreverseMessage()
を定義すると、this.message
の値が変化した時にしかreverseMessage()
メソッドは再実行されません。
つまり、this.message
の値が変化しない限り「再度メソッド実行することなく以前計算された結果を即時に返してくれる」のです。
ただし、下記の様にmethodsで定義してしまうと:
methods: { reverseMessage: function () { return this.message.split('').reverse().join('') } }
this.message
の値が変化しようがしまいが、reverseMessage()
はレンダリング時に常に再実行されます。
じゃあmethodsってどういう時に使うのかというと、下記の様な「算出結果をキャッシュして欲しくない処理」に使用するとよいようです。
例えば、下記の様なDate.now()
を使用する処理を算出プロパティで書いてしまうと…
computed: { now: function () { return Date.now() } }
Date.now()
の変更はVue.jsでは検知できないため、このメソッドは「実行されてから永遠に返却値が変わらないメソッド」となってしまいます。コマッタ!
こういう関数を使いたいときは、methodsを使えということでしょうね。
補足: watchについて
「値の変更を検知し」「検知されたら実行する」処理をしたい時に…。
Vue.jsでは「監視プロパティ(watch)」というものが提供されています。
ただ、公式Wikiには「大概の場合はcomputedを使う方がいい」とありました。
その理由は下記のコードを見比べればわかるかと:
<div id="demo">{{ fullName }}</div>
// watch使用Ver var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName = val + ' ' + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ' ' + val } } })
computed使用Ver var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: function () { return this.firstName + ' ' + this.lastName } } })
上記の例だとfullName
がfirstName
とlastName
に依存するため、computedでひとまとめに処理した方が良かったですが…。
1つの値によって、アプリケーションの状態が繊細に変化する様な状況ではwatchの方が良さそうですね。
補足: computedを深掘りしてみる
公式記事を元に、computedが具体的にどんな振る舞いをするのかもみてみました。
jp.vuejs.org
というか公式記事、チュートリアルだけでなく内容の深いところまでしっかり書いてくれているからすごく参考になりますね…。
若干説明が分かりにくいので、こうして別途記事にまとめた方が理解しやすいですが。
閑話休題。
例えばこんな感じのコードがあるとします:
<div id="example"> <p>元々のメッセージ: "{{ message }}"</p> <p>反転したメッセージ: "{{ reversedMessage }}"</p> </div>
var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 算出 getter 関数 reversedMessage: function () { // `this` は vm インスタンスを指します return this.message.split('').reverse().join('') } } })
こういう風に書くことで、reversedMessage
は「プロパティvm.reversedMessage
に対するgetter関数」として宣言されます。
そしてさらに、この値はvm.message
に常に依存するようになっており。
これにより、Vue.js側がmessage
とreversedMessage
の依存関係を知ることができるため…。
「message
が変更されたらmessage
に依存している他の処理(ここでいうとreversedMessage
ですね)も再実行される」様にできるのです!
computedはこの様にして、依存している値と連動できてるんですなぁ。
おわりに
今回はチュートリアルで作成したコードのカスタマイズの中で気になった項目3つ:
- Vuexとは?
- computedとmethodsの違い
- propsとdataの違い
…の内、「computedとmethodsの違い」について見ていきました。
computedとmethodsの他にも、watchについてもまとめちゃうことになりましたね…。
これら3項目について、本記事では「各項目が何を示すのか」に着目してまとめていきましたが…。
純粋に各項目の比較をしたいなら、こちらの記事が分かりやすくておすすめです。
qiita.com
次回記事では、最後となる「propsとdataの違い」について見て行ければと。
それでは|д゚*)