Vue.js　算出プロパティ

#Vue.js　算出プロパティ

前回の記事はこちら
[Vue.jsで使えるjavascript式とフィルタの使い方](https://qiita.com/fumiya0414/items/95361a25965e0c112d67#%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)

[jsfiddle](https://jsfiddle.net/)で実際に記述しながら読むことをおすすめします。

##算出プロパティ
算出プロパティは関数によって算出したデータを返します。
以下の４つを紹介します。

算出プロパティの基本
算出プロパティとメソッドの比較
算出プロパティのgetterｍとsetter
算出プロパティのキャッシュ

##算出プロパティの基本
まずは以下のコードを見て下さい。

```html:index/html
<div id="app">

<p>{{ message.split('').reverse().join('') }}</p>

</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    message:"Hello Vue.js!"
  }
})
```
実行結果
[![Image from Gyazo](https://i.gyazo.com/346f7011b8d55c11bc93de4d903b0658.png)](https://gyazo.com/346f7011b8d55c11bc93de4d903b0658)

マスタッシュ構文{{}}の中で文字列を
逆にする処理を行っています。

しかしプログラムが大きくなるにつれて
マスタッシュ構文内の可読性が悪く
コード全体の見通しが悪化する恐れがあります。

算出プロパティcomputedを使用して書き換えてみます。

```html:index/html
<div id="app">

<p>{{ message.split('').reverse().join('') }}</p> 
<p>{{ reversedMessage}}</p> <!--算出プロパティで書き換え-->

</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    message:"Hello Vue.js!"
  },
  //以下算出プロパティ
  computed:{
    reversedMessage:function(){
      return this.message.split('').reverse().join('')
    }
  }
})
```
実行結果
[![Image from Gyazo](https://i.gyazo.com/2a448866d09d98939bb42041b4f4de50.png)](https://gyazo.com/2a448866d09d98939bb42041b4f4de50)

上記のように算出プロパティを使うことで処理の記述をjs側に
まとめることができるためhtmlの可読性が担保できます。

また処理の再利用が増えた場合も簡単になります。

##算出プロパティとメソッドの比較

算出プロパティもメソッドもデータを取って
表示するだけなら動作は同じに見えます。
以下は比較例です。

```html:index/html
<div id="app">

　<p>{{ reversedMessage }}</p>
　<p>{{ reversedMessageMethod() }}</p>

</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    message:"Hello Vue.js!"
  },
  computed:{
    reversedMessage:function(){
      return this.message.split('').reverse().join('')
    }
  },
  methods:{
    reversedMessageMethod:function(){
      return this.message.split('').reverse().join('')
    }
  }
})
```
実行結果
[![Image from Gyazo](https://i.gyazo.com/ee52a64ed6a94c7f47cd02e6c0046691.png)](https://gyazo.com/ee52a64ed6a94c7f47cd02e6c0046691)

###違いその１　引数の有無
処理の内容は同じですが
算出プロパティは()が無し　　メソッドは()が有り
と引数の有無に違いがあります。

###違いその２　setter/getter
算出プロパティは必要に応じてsetter/getterいずれも持つことができます。
メソッドはgetterしか持つことができません。

税抜/税込みの計算を例に見てみましょう。

```html:index/html
<div id="app">

<p>
  base price: <input type="text" v-model="basePrice"> <!--税抜（本体）価格-->
</p>

<p>
  tax included price: <input type="text" v-model="taxIncludedPrice"><!--税込価格-->
</p>

</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    basePrice: 100
  },
  computed:{
    taxIncludedPrice: {
      get: function(){  //getter
        return parseInt(this.basePrice * 1.08)
      },
      set: function(taxIncludedPrice){  //setter
        this.basePrice = Math.ceil(taxIncludedPrice / 1.08)
      }
    }
  }
})
```
実行結果
[![Image from Gyazo](https://i.gyazo.com/1832b8379e901d6c7d327952a84561a7.gif)](https://gyazo.com/1832b8379e901d6c7d327952a84561a7)
perseInt関数・・・整数を返す
Math.ceil関数・・・小数点を切り上げる

getter側の流れ
①上のinputタグに入力されたbasePriceがv-modelディレクティブでdataプロパティに渡される
②taxIncludedにてbasePriceはgetterとして渡され1.08倍されて下のinputタグに描画

setter側の流れ
①下のinputタグに入力されたtaxIncludedPriceはsetterとして/1.08の処理される
②v-modelディレクティブによってdataプロパティのbasePriceとして渡されて上のinputタグに描画

算出プロパティではdataからgetで受け取ったデータを処理することも
処理をしてからdataへsetでデータを渡すことも可能という意味です。

###違いその3　キャッシュ
算出プロパティはキャッシュされます。
メソッドはキャッシュされません。

キャッシュとは呼び出されるたびに処理が走るか走らないかの違いです。
プログラムが大きくなるにつれて処理の有無がスピードに影響します。

こちらは乱数を3回繰り返す処理を例にします。

```html:index/html
<div id="app">

<h3>算出プロパティ</h3>
<p>{{ computedNumber }}</p>
<p>{{ computedNumber }}</p>
<p>{{ computedNumber }}</p>

<h3>メソッド</h3>
<p>{{ methodsNumber() }}</p>
<p>{{ methodsNumber() }}</p>
<p>{{ methodsNumber() }}</p>

</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
	el:'#app',
    computed:{
      computedNumber:function(){
        return Math.random()    
      }
    },
    methods:{
      methodsNumber:function(){
      return Math.random()
    }
  }
})
```
実行結果
[![Image from Gyazo](https://i.gyazo.com/0291de67802babfe2600df908750c8ad.png)](https://gyazo.com/0291de67802babfe2600df908750c8ad)

算出プロパティでは1度取得した値は再処理されずにキャッシュされています。
一方メソッドは1行ごとに処理が走り異なる乱数が３回取得されます。

そのため算出プロパティのほうが早く処理が可能ですが
あえてキャッシュさせない場合はメソッドを使いましょう。

次回は監視プロパティです。
[Vue.js　監視プロパティ](https://qiita.com/fumiya0414/items/ba37ddcfc632ed546e12)