前置き
 データの変更の監視ができる
監視プロパティのwatch💥👀
算出プロパティとの比較を中心に
解説していきます🍓🙋♀️
公式: https://jp.vuejs.org/v2/guide/computed.html
算出プロパティ VS 監視プロパティ

inputに入力したデータの変更を検知して
表示もそれに応じて変えてます💫
でもこの場合ならcomputed使った方が早くない?🤷♀️
とVue公式も言っています。
じゃあwatchいつ使うんだ!😡
というのは後述するので
まずは違いを見てみましょう👀⚡️
❌ watch
入力するinputの値を
全てを監視するので
とっても面倒ですね、
ほぼ同じことを書きます✍️💦
⭕️ computedfullNameの1つにまとまるので
スッキリします✨
⬇️computedの解説記事はこちら
監視プロパティwatch
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <template>   <div>     <input type="text" v-model="firstName">     <input type="text" v-model="lastName">     <p>{{ fullName }}</p>   </div> </template> <script> export default {   data () {     return {       firstName: 'Foo',       lastName: 'Bar',       fullName: 'Foo Bar'     }   },   watch: {     firstName (value) {       this.fullName = value + '' + this.lastName     },     lastName (value) {       this.fullName = this.firstName + '' + value     },   }, } </script> | 
算出プロパティcomputed
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <template>   <div>     <input type="text" v-model="firstName">     <input type="text" v-model="lastName">     <p>{{ fullName }}</p>   </div> </template> <script> export default {   data () {     return {       firstName: 'Foo',       lastName: 'Bar',     }   },   computed: {     fullName () {       return this.firstName + '' + this.lastName     }   }, } </script> | 
watchにしかできないこと

多くの場合は算出プロパティが適切だけどwatchにしかできないこともあります🌟
APIを使ったり、処理の実行頻度を制限したり。
この場合では、
https://jp.vuejs.org/v2/guide/computed.htmlwatchオプションを利用することで、非同期処理(API のアクセス)の実行や、処理をどのくらいの頻度で実行するかを制御したり、最終的な answer が取得できるまでは中間の状態にしておく、といったことが可能になっています。これらはいずれも算出プロパティでは実現できません。
解説
watch
watchの使い方はこちら。
オプションも使えますが、
今回は使わないので
最低限の基礎構文のみ
記載しています✍️
| 1 2 3 4 5 | watch: {    変更を監視するプロパティ名を記述: function (変更後の値, 変更前の値) {       ここに処理内容を記述    } } | 
inputの値を監視し、
値が変わっている間のテキストを表示させ、debouncedGetAnswer()を呼び出します。
公式: https://jp.vuejs.org/v2/api/#vm-watch
参考: https://www.e-loop.jp/knowledges/2/
created()
解説記事をご覧ください❤️👀
_.debounce(function, wait, [immediate])
イベント発火後、
指定秒数で同じイベントを発火させずに留める。
この場合は質問が入力されてから0.5秒後に実行。
最大で0.5秒に1回しか実行されません。
参考: 
http://underscorejs.org/#debounce
https://qiita.com/akifo/items/4d715929934a458fb189
indexOf(string)
指定されたStringが
最初に現れたインデックスを返します。
値がなければ-1を返します。
今回は?を指定しているので
質問に?がなく-1を返す場合は
「?を入れてね」と言われます🧸
?がある場合は
Thinking...が表示されます。
参考: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
axios
yesnoAPIを使うのでaxios🌟
1万回に1回maybeが
返されることもあるみたいです😄
yesnoAPI: https://yesno.wtf/#
⬇️axiosの解説記事はこちら
_.capitalize(string)
指定された文字の
先頭のみ大文字、
あとは小文字にします。
https://yesno.wtf/apiを見ると
yesかnoが表示されるので
先頭を大文字にするために
使用していますね💡
コード
lodashはグローバルなモジュールで
importの必要はないとあるけど
importしないとエラーに
なってしまいました。。。
参考: https://ja.nuxtjs.org/faq/webpack-plugins/
Error
ReferenceError: _ is not defined
でもimportすれば良いだけなので…!
これでしっかり動きます🌟🤗
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <template>   <div class="page">     <p>Ask a yes/no question:</p>     <input v-model="question">     <p>{{ answer }}</p>   </div> </template> <script> import _ from 'lodash' import axios from 'axios' export default {   data () {     return {       question: '',       answer: 'I cannot give you an answer until you ask a question!',     }   },   watch: {     // この関数は question が変わるごとに実行されます。     question (newQuestion, oldQuestion) {       this.answer = 'Waiting for you to stop typing...'       this.debouncedGetAnswer()     }   },   created () {     // _.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         })     },   }, } </script> | 
まとめ
基本的には算出プロパティを使い、
ダメならwatch❗️👀
非同期通信など
少し複雑な処理が必要なら❗️watch👀
というように
実装したい内容に合わせて
使い分けましょう🎶🎷
