Vue.js始めるおれおれアドベントカレンダー2016 – 6日目
Vueでは data
, methods
の他に、両者の特性を併せ持った computed
というものを指定することができます。これすげーんでお見知りおきください。
- 公式ドキュメント: 算出プロパティとウォッチャ – vue.js
- デモ
- コード
data
と methods
この二つはまあ普通なんですが、 data
がデータ、 methods
がメソッドです。そのまんまだ。
イニシャルを表示する例
JS側で getInitial()
というメソッドを実装して、HTML側で {{getInitial()}}
と書いて呼び出しています。
<div id="app"> <p> <label> First Name: <input v-model="firstName" type="text" /> </label> <br /> <label> Last Name: <input v-model="lastName" type="text" /> </label> </p> <h1>Hello {{getInitial()}}!</h1> </div>
var app = new Vue({ el: '#app', data: { firstName: 'ginpei', lastName: 'takanashi', }, methods: { getInitial: function() { var firstFirstNameLetter = this.getInitialOf(this.firstName); var firstLastNameLetter = this.getInitialOf(this.lastName); var initial = firstFirstNameLetter + '.' + firstLastNameLetter + '.'; return initial; }, /** * @param {string} name * @returns {string} * @example * this.getInitialOf("alice"); // => "A" */ getInitialOf: function(name) { return name.charAt(0).toUpperCase(); }, }, });
まあ普通ですね。
computed
computed
を使うと、先ほどの例がこう書けます。(だいたい一緒なので違う部分だけ。)
<h1>Hello {{initial}}!</h1>
computed: { initial: function() { var firstFirstNameLetter = this.getInitialOf(this.firstName); var firstLastNameLetter = this.getInitialOf(this.lastName); var initial = firstFirstNameLetter + '.' + firstLastNameLetter + '.'; return initial; }, },
HTML側では data
のように名前を書くだけ、JS側では methods
のように関数を実装しています。
何かをあれこれ処理しているのではなくて、ここでは(処理した)結果をただ表示するぞ、というのが分かりやすいかと思います。え、そうでもない?
キャッシュ
メソッドとの最大の違いは、結果がキャッシュされ毎回実行されないという点です。
ドキュメントから引用します。( message
が data
に格納されており、それを順序反転する処理 reversedMessage
が computed
で定義されている文脈です。)
算出プロパティの代わりに、同じような関数をメソッドとして定義することも可能です。最終的には、2つのアプローチは完全に同じ結果になります。しかしながら、算出プロパティは依存関係にもとづきキャッシュされるという違いがあります。算出プロパティは、それが依存するものが更新されたときにだけ再評価されます。これはつまり、
message
が変わらない限りは、reversedMessage
に何度アクセスしても、関数を再び実行することなく以前計算された結果を即時に返すということです。
参照している値を自動的に監視して、最低限の実行で処理してくれるそうです。すんげー。
注意点
逆に、 data
の値を参照していない場合、例えば先のドキュメントでは Date.now()
が使われていましたこういう場合には、キャッシュされた値は更新されなくなってしまうようです。
メソッドはあまり使わない?
というわけで画面に出力する計算は computed
でやるのが良さそうです。
Date.now()
みたいにVue外から情報を得る場合は、取得した結果を data
に入れてそれを computed
で出力するーみたいな感じでしょうか。コンポーネントなら porps
経由で。
するとメソッドを使う場面は、今回みたいにDRY的に単純に処理をまとめるのと、イベントハンドラを定義するのくらいでしょうか。
ユーザー一覧の各項目で情報を加工する場合はどうだろ。 doSomething(list[i])
みたいなのが必要? いやコンポーネントに分けて、子の方で porps
で受けた値を computed
でやれば良さそう。
というのを作ってみた:
うーんこんな感じなんだろうか。日時情報の扱いはもっと上手にやれそうな気がする?