iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 11
0

菜菜菜的 Vue 30天 - Day11

watch

這個章節要介紹的就是 watch ,看著這個方法的名稱就應該大概知道功能是什麼了。

它就是在那靜靜的看著你,等到你動了,它也就跟著動了!!

情境大概就是這樣~

它會監聽一個值,如果這個值有改變,它就會觸發來執行開發者所指定要執行的動作。

這樣講可能很抽象,這就來用程式碼講解一下吧:

watch 一樣是一個物件的格式,它裡面宣告的必須跟你要監聽的對象是一樣的命名。

就像下面這段程式,我要監聽 data 內的 message,那我在 watch 裡面也要宣告一個一樣名為 message 的監聽。

接下來 watch 內能夠帶 2 個參數 valandoldVal,顧名思義就是改變後的值以及改變前的值,我們就能夠針對這些參數去執行操作。

<body>
  <div id="app">
    <input type="text" v-model="message">
  </div>
</body>
<script>
  const vm = new Vue({
    el: '#app',
    data: {
      message: ''
    },
    watch: {
      message(val, oldVal) {
        console.log(val, oldVal);
      }
    }
  })
</script>

我們一樣來實際看一下效果:

而 watch 不只可以監聽 data 它也能夠監聽 computed,我們就拿上一章練習的 BMI 產生器來練習吧~

前面的 code 都一樣,只是多了一個 watch 的部分

<body>
  <div id="app">
    身高:<input type="number" v-model="height" placeholder="請輸入您的身高"><br>
    體重:<input type="number" v-model="weight" placeholder="請輸入您的體重"><br>
    您的 BMI 為:{{bmi}}
  </div>
</body>
<script>
  const vm = new Vue({
    el: '#app',
    data: {
      weight: null,
      height: null
    },
    computed: {
      bmi() {
        const weight = parseInt(this.weight, 10);
        const height = parseInt(this.height, 10) / 100;
        const bmi = weight / (height * height);
        return bmi || 0;
      }
    },
    watch: {
      bmi(val, oldVal) {
        const diff = val - oldVal
        diff > 0 ? alert('變胖了哦,阿餒母湯~') : alert('變瘦了餒,美麥美麥~~');
        // 這邊是一個三元運算式,如果看不懂的話可以 google 一下唷~
      }
    }
  })
</script>

我 watch 的部分去監聽 bmi 這個 computed,就來看一下效果吧~

immediate && deep

watch 除了上面介紹的方式宣告之外,還能夠將它宣告成 object 的格式,宣告成 object 後能夠使用幾個方法 handlerimmediateanddeep

剛剛上面所介紹的使用方式就是 handler。

immediate

而 immediate 的部分就是在監聽的值初始化的時候就監聽了,也就是假設我監聽一個 data 它預設值為 0,那 watch 會監聽到 data 從 undefined0,如下:

<script>
  const vm = new Vue({
    el: '#app',
    data: {
      number: 0
    },
    watch: {
      number: {
        handler: function(val, oldVal) {
          console.log(`val: ${val}`, `oldVal: ${oldVal}`);
        },
        immediate: true
      }
    }
  })
</script>

我將頁面重整,他在初始化時就監聽到我的 oldVal: undefined => val: 0

deep

再來 deep 是如果我們今天要監聽的值是一個 Array or Object 的話就必須要加上 deep: true,如果沒有加上 deep: true 我們監聽 Array or Object 是沒辦法間聽到它內部值的改變。

就像是 ES6 新的宣告方式 const,我們使用 const 宣告一個 Number or String ...等,都不能夠再做改變,但是如果我們宣告的是一個 Array or Object 它裡面的值還是能夠被改變的,不能改變的是它不能從 Array or Object 變成 Number 或其他型別。

話題拉回來,只要我們加上 deep: true 我們就能夠間聽到 Array or Object 內部的值,如下:

先來看一下如果沒有加上 deep 會是如何~

<body>
  <div id="app">
    <input type="text" v-model="object.x">
  </div>
</body>
<script>
  const vm = new Vue({
    el: '#app',
    data: {
      object: {
        x: ""
      }
    },
    watch: {
      object: {
        handler: function(val, oldVal) {
          console.log(`val: ${val}`, `oldVal: ${oldVal}`);
        }
      }
    }
  })
</script>

我在輸入的時候他就沒有監聽到 object 有改變,因為他還是一個 object~

那我們來把 deep 加上去吧~

watch: {
  object: {
    handler: function(val, oldVal) {
      console.log(`val: ${val}`, `oldVal: ${oldVal}`);
    },
    deep: true
  }
}

加上去之後我們就能夠間聽到 object 裡面值的改變囉~

今天就到這邊囉~

下課!! ㄙㄨㄚˋ!!!


上一篇
BMI 產生器
下一篇
條件渲染(v-if、v-else、v-else-if 及 v-show)
系列文
菜菜菜的 Vue 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言