vue計算プロパティとリスナー

17390 ワード

vueはテンプレートで式を使用するのは便利ですが、単純な演算に使用することを目的として設計されています.テンプレートに論理を入れすぎると、テンプレートが重すぎてメンテナンスが困難になります.
計算プロパティ
<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

複雑な論理では、計算プロパティを使用します.例:
<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ 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関数
計算プロパティは、通常のプロパティをバインドするようにテンプレートにバインドできます.Vueはvmを知っている.reversedMessageはvmに依存する.Message、だからvm.Messageが変化する場合、すべての依存vm.reversedMessageのバインドも更新されます.さらに、最も素晴らしいのは、属性を計算するgetter関数に副作用(side effect)がないことであり、テストと理解を容易にするという依存関係が宣言されていることです.
計算プロパティ&メソッド
式でメソッドを呼び出すと、計算プロパティと同じ効果が得られます.
<p>Reversed message: "{{ reversedMessage() }}"</p>
//     
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

しかし、計算プロパティは応答依存性に基づいてキャッシュされる点が異なります.相関応答依存が変更された場合にのみ、値が再評価されます.これは、messageが変更されていない限り、reversedMessage計算プロパティに複数回アクセスすると、関数を再実行する必要がなく、前の計算結果がすぐに返されることを意味します.
これは、Dateのため、次の計算プロパティが更新されないことを意味します.now()は応答依存ではない
computed: {
  now: function () {
    return Date.now()
  }
}

対照的に、呼び出し方法は、再レンダリングがトリガーされるたびに関数を再実行します.
なぜキャッシュが必要なの?パフォーマンスオーバーヘッドの大きい計算プロパティAがあると仮定します.大きな配列を巡り、大量の計算を行う必要があります.そして、他の計算属性がAに依存する可能性があります.キャッシュがなければ、Aのgetterを複数回実行することは避けられません.キャッシュを望まない場合は、代わりに方法を使用します.
計算プロパティ&リスニングプロパティ
Vueは、Vueインスタンス上のデータ変動:リスニング属性を観察し、応答するためのより一般的な方法を提供する.他のデータの変動に伴って変更する必要があるデータがある場合、watchを乱用しやすく、コマンド式のwatchコールバックではなく計算属性を使用するのが一般的です.計算プロパティのデフォルトはgetterのみですが、必要に応じてsetterを指定することもできます.
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

リスナー
計算プロパティはほとんどの場合適切ですが、データの変化に応答するためにカスタムリスナーが必要になる場合があります.データの変化時に非同期またはオーバーヘッドの大きい操作を実行する必要がある場合、watch方式が最も有用である.
<div id="watch-example">
  <p>
    Ask a yes/no question:
    <input v-model="question">
  </p>
  <p>{{ answer }}</p>
</div>

var watchExampleVM = new Vue({
  el: '#watch-example',
  data: {
    question: '',
    answer: 'I cannot give you an answer until you ask a question!'
  },
  watch: {
    //    `question`     ,        
    question: function (newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  },
  created: function () {
    // `_.debounce`       Lodash          。
    //       ,         yesno.wtf/api    
    // AJAX               。        
    // `_.debounce`    (     `_.throttle`)    ,
    //    :https://lodash.com/docs#debounce
    this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
  },
  methods: {
    getAnswer: function () {
      if (this.question.indexOf('?') === -1) {
        this.answer = 'Questions usually contain a question mark. ;-)'
        return
      }
      this.answer = 'Thinking...'
      var vm = this
      axios.get('https://yesno.wtf/api')
        .then(function (response) {
          vm.answer = _.capitalize(response.data.answer)
        })
        .catch(function (error) {
          vm.answer = 'Error! Could not reach the API. ' + error
        })
    }
  }
})

watchオプションを使用すると、非同期操作(APIへのアクセス)を実行し、その操作を実行する頻度を制限し、最終結果が得られる前に中間状態を設定できます.これらは計算プロパティではできません.
参照先:https://cn.vuejs.org/v2/guide/computed.html