16
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ReluxAdvent Calendar 2018

Day 22

Vue.js 算出プロパティを活用すべきというお話

Last updated at Posted at 2018-12-21

#はじめに
私自身、あまり説明書を読まない派の人間です(子供の頃は熟読してたけどいつの間にか変わっていた)。
なにかしらの技術を新しく学ぶとなったときももちろん勉強のフェーズではドキュメント読んだり参考書読んだりするわけですが中々隅々まで目を通せていないことが多いです。これが原因でソースレビューで「これ使ったほうがいいよ」と便利・有用なモノを教えてもらうこともしばしば。

今回は私と似た性格の人・Vueをこれから学ぶよって方へ向けた、Vueの「算出プロパティ」について紹介します。

#算出プロパティとは
あるデータに依存しているデータ(Aを元に生成されるBのような)がある場合、Vueでは何種類かの実装手段があります。
文章だと分かりづらいのでまずは例を・・・
入力値「苗字」と「名前」(上の説明でいうA)を元に、フルネーム(上の説明でいうB)を表示する処理を各手段ごとに書いてみました。
スクリーンショット 2018-12-21 16.38.57.png

↑こんな感じです。各ケース、入力値に応じてフルネームがリアルタイムで更新されます。

・テンプレートに直接書く方法

<div id="test">
  苗字<input v-model="lastName"><br>
  名前<input v-model="firstName">
  <p>Full Name: {{ lastName + ' ' + firstName }}</p>
</div>
var vm = new Vue({
  el: '#test',
  data: {
    lastName: '',
    firstName: '',
  }
})

この例の処理くらいだったらまだマシですが、基本的にテンプレートに処理は書きたくないですよね。

・処理をメソッドに切り出す方法

<div id="test">
  苗字<input v-model="lastName" v-on:keyup="updateName"><br>
  名前<input v-model="firstName" v-on:keyup="updateName">
  <p>Full Name: {{ fullName }}</p>
</div>
var vm = new Vue({
  el: '#test',
  data: {
    lastName: '',
    firstName: '',
    fullName: ''
  },
  methods: {
   updateName: function () {
      this.fullName = this.lastName + ' ' + this.firstName
    }
  }
})

無事にテンプレートから処理を切り出すことができました。
しかし、たったこれだけのことなのにテンプレート側がややごちゃごちゃしてしまいました。

・監視プロパティで実装する方法

<div id="test">
  苗字<input v-model="lastName"><br>
  名前<input v-model="firstName">
  <p>Full Name: {{ fullName }}</p>
</div>
var vm = new Vue({
  el: '#test',
  data: {
    lastName: '',
    firstName: '',
    fullName: ''
  },
  watch: {
    lastName: function (val) {
      this.fullName = this.lastName + ' ' + this.firstName
    },
    firstName: function (val) {
      this.fullName = this.lastName + ' ' + this.firstName
    }
  }
})

watchを利用してlastNameとfirstNameの更新を監視しており、更新があったらfullNameを再生成する動きです。methodsでの実装と比較するとテンプレート側はスマートになりますが、処理側が冗長になっています。

・算出プロパティ

<div id="test">
  苗字<input v-model="lastName"><br>
  名前<input v-model="firstName">
  <p>Full Name: {{ fullName }}</p>
</div>
var vm = new Vue({
  el: '#test',
  data: {
    lastName: '',
    firstName: ''
  },
  computed: {
   fullName: function () {
      return this.lastName + ' ' + this.firstName
    }
  }
})

いかがでしょうか。パッと見でもスマートになった感があると思います。
算出プロパティであるfullNameは、依存するデータ(lastName,firstName)に更新が入ったときのみ自動で処理が実行され、キャッシュされます
つまり、依存するデータに更新がない状態で再描画が走っても処理は実行されず、キャッシュから即時にデータを取り出します。この程度の処理であれば差を感じることはありませんが、Vue側で膨大な量のデータを加工しないといけないといったケースにおいてはマストで利用していきたい機能です。

#デメリット
処理実行頻度の制御など、一部のケースにおいて算出プロパティでは実現できないものが存在します。(公式ドキュメントに例があるのでそちらを参照願います)
https://jp.vuejs.org/v2/guide/computed.html#%E3%82%A6%E3%82%A9%E3%83%83%E3%83%81%E3%83%A3

#あとがき
先に述べましたが、実際算出プロパティを使わなくても実装上は困らないためドキュメントをあまり読まない人は知らずに実装進めちゃいそうだなと思い(自戒も込めて)紹介させていただきました。
可読性やパフォーマンス面等において利用できるならしたほうがいいケースがほとんど(できるのにあえてしないケースが思い浮かばない)ではないでしょうか。
ReluxにおいてVueを利用するかどうかはまだ検討中ですが、利用するときはまず「算出プロパティが適用できるか」から考え、それが難しかった場合に適宜ウォッチャ等で実装していくという進め方を心がけていこうと思います。

16
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?