vueの中のウォッチについて話します。


ウォッチ
計算属性は多くの場合より適切ですが、カスタムウォッチが必要な場合もあります。これはなぜVueがより一般的な方法を提供しているのですか?watchオプションによってデータの変化に応答します。データ変化応答の場合には、非同期動作またはオーバーヘッドの大きな動作を実行することが有用である。
みんなはウオッチに慣れていないはずです。プロジェクトでは以下のような書き方をしました。

watch: {
 someProp () {
  // do something
 }
}
//   
watch: {
 someProp: {
  deep: true,
  handler () {
   // do something
  }
 }
}
上記の書き方はVueに教えてくれました。私はsomeProp属性の変化を監督してもらいたいです。そしてvueは内部でwatchオブジェクトを作成してくれます。紙面に限られています。ウォッチの具体的な実現については話さないで、興味がある人は直接ソースウォッチを見ることができます。
しかし、vueでは、watchの機能はこのように単一ではありません。

<template>
 <div>
  <p>a: {{ a }}</p>
  <p>b: {{ b }}</p>
  <button @click="increment">+</button>
 </div>
</template>
<script>
export default {
 data () {
  return {
   a: 1
  }
 },
 computed: {
  b () {
   return this.a * 2
  }
 },
 watch: {
  a () {
    console.log('a is changed')
  }
 },
 methods: {
  increment () {
   this.a += 1
  }
 },
 created () {
  console.log(this._watchers)
 }
}
</script>
オンラインデモ
上のコードはとても簡単です。私達は今主にcreatedフックに印刷されたthisに注目しています。ウォッチは以下の通りです
三つのウォッチをそれぞれ展開し、それぞれのexpressionを観察し、上から下までそれぞれ:

b() {   return this.a * 2;↵  }
"a"
function () {   vm._update(vm._render(), hydrating);↵  }
上の三つのウォッチは三つの異なる機能のウォッチを表しています。機能によって三つの種類に分けられます。
  • は、watchで定義されており、属性の変化を監督するためのウォッチ(第二の)
  • である。
  • は、computted属性のウォッチ(最初の)
  • に使用されます。
  • ページ更新のためのウォッチ(3番目)
  • normal-watch
    私たちがwatchで定義したのは、このタイプです。つまりモニターの属性が変わったら、定義されたコールバック関数をトリガします。
    computted-ウォッチ
    各computted属性は、最後に対応するウォッチオブジェクトを生成しますが、このようなウォッチには特徴があります。上記のbを例に挙げます。
    属性bはaに依存しています。aが変更された場合、bはすぐに再計算されません。その後、他のところでbを読み込む必要がある場合、それは本当に計算されます。すなわち、lazy(怠け者計算)の特性を備えています。
    レンダーウォッチ
    各コンポーネントには render-watcher, function () {↵ vm._update(vm._render(), hydrating);↵ }があります。data/computted
    のプロパティが変更されたときは、このrender-watchを呼び出してコンポーネントの表示を更新します。
    三つのウォッチの実行順序
    機能の違い以外にも、この三つのウォッチは固定された実行順序があります。それぞれ:
    
    computed-render -> normal-watcher -> render-watcher
    このように手配するのは原因があって、このようにできるだけの保証をすることができて、コンポーネントビューを更新する時、computted属性はすでに最新値で、もしrender-watchがcomputted-renderの前に並ぶならば、ページの更新を招くことができる時computed値は古いデータです。
    次は具体的なコードの中からvueの中のウォッチを見ます。
    この例では、watchオプションを使用して、非同期動作(APIにアクセス)を実行することができます。この動作の周波数を制限し、最終結果を得る前に中間状態を設定します。これは属性を計算することができません。
    
    <div id="watch-example">
    <p>
    Ask a yes/no question:
    <input v-model="question">
    </p>
    <p>{{ answer }}</p>
    </div>
    <!-- Since there is already a rich ecosystem of ajax libraries -->
    <!-- and collections of general-purpose utility methods, Vue core -->
    <!-- is able to remain small by not reinventing them. This also -->
    <!-- gives you the freedom to just use what you're familiar with. -->
    <script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
    <script src="https://unpkg.com/[email protected]/lodash.min.js"></script>
    <script>
    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) {
    this.answer = 'Waiting for you to stop typing...'
    this.getAnswer()
    }
    },
    methods: {
     // _.debounce       lodash          。
     //       ,        yesno.wtf/api   
     // ajax              
     //        _.debounce function (and its cousin
    // _.throttle),   : https://lodash.com/docs#debounce
    getAnswer: _.debounce(
    function () {
    var vm = this
    if (this.question.indexOf('?') === -1) {
    vm.answer = 'Questions usually contain a question mark. ;-)'
    return
    }
    vm.answer = 'Thinking...'
    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
    })
    },
    //                  
    500
    )
    }
    })
    </script>
    結び目
    本文はソース解析のような文章ではなく、ただ一つの角度から雑談するだけで、関連していないように見えるもの(computed/watch/ページ更新)は、内部に緊密な連絡があります。