iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 8
0

https://ithelp.ithome.com.tw/upload/images/20171218/20107107t4h3l6FYNm.png

Watch

雖然在大多數情況下,Computed 更合適,但有時仍需要使用 Watch。

Watch vs Computed

附上 fiddle (https://jsfiddle.net/hunterliu/s3rg5s5c/)

<div id="app">
  <p>fullName (computed):${ fullName }</p>
  <p>fullName (watch):${ fullNameWatch }</p>
</div>
var vm = new Vue({
  el: '#app',
  delimiters: ['${', '}'],
  data: {
    firstName: 'John',
    lastName: 'Doe',
    fullNameWatch: 'John Doe' // watch 需手動設置初始值
  },
  computed: {
    fullName: function() {
      return this.firstName + ' ' + this.lastName;
    }
  },
  watch: {
    firstName: function(val) {
      this.fullNameWatch = this.firstName + ' ' + this.lastName;
    },
    lastName: function(val) {
      this.fullNameWatch = this.firstName + ' ' + this.lastName;
    }
  }
});

vm.$data.firstName = 'Jane';

使用 computed 或 watch 皆可得到同樣的效果,但 computed 會是一個更好的選擇 - 更精簡易懂。

Watch 基礎範例

當你需要響應更改的數據執行非同步或複雜的計算時,Watch 就非常有用。
下面的範例使用 v-model 綁定 input 的值為 question,當使用者輸入問題時會執行 watch 的 question 函式,並執行 getAnswer,再送出 AJAX 去取得問題的答案。

附上 fiddle (https://jsfiddle.net/hunterliu/2tc0dd3o/1/)

<div id="watch-example">
  <p>
    Ask a yes/no question:
    <input v-model="question">
  </p>
  <p>{{ answer }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
var watchExampleVM = new Vue({
  el: '#watch-example',
  data: {
    question: '',
    answer: 'I cannot give you an answer until you ask a question!'
  },
  watch: {
    // whenever question changes, this function will run
    question: function (newQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.getAnswer()
    }
  },
  methods: {
     getAnswer: _.debounce(
      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
          })
      },
      500
    )
  }
})

注意:

getAnswer 函式中使用了 lodash.js 的 debounce 函式,並設定在使用者輸入停止 500 毫秒後,會先確認這個問題包含了'?',接著才發送 AJAX 去取得問題的答案,目的是為了避免使用者在輸入完問題之前,就發送不必要的 Request。

vm.$watch 與 immediate

附上 fiddle (https://jsfiddle.net/hunterliu/gtpyLcc9/)

參考資料


上一篇
用範例理解 Vue.js #7:Filters vs Computed
下一篇
用範例理解 Vue.js #9:v-bind and Class Bindings
系列文
用範例理解 Vue.js30

尚未有邦友留言

立即登入留言