Vue中Watch偵聽器的簡單用法


目錄

1.computed計算屬性

1.1. computed的簡單例子

1.2.computed計算屬性的setter

2.Watch偵聽器

2.1.簡單的watch偵聽

2.2.handler、immediate

2.3.監聽對象、數組等(deep屬性) 

 2.4.監聽字符串形式

2.5.監聽多個對象


之前做過關於數據不是定值,而是由其他數據計算而得來的頁面。

以前學藝不精,只會一些Vue的簡單用法,所以之前都是用的methods方法,在輸入框上綁定input或者change事件,輸入數據時,修改結果的效果,來達到數據動態由其他數據計算得來的。

后來隨着Vue的使用越來越多,對Vue的其他知識點也開始逐漸多了解一點,這次做頁面上的計算,用了Watch偵聽器,這里簡單記錄一下自己在使用過程中遇到的問題和一些總結。

1.computed計算屬性

說到Watch偵聽器,就順便記錄一下computed計算屬性。

1.1. computed的簡單例子

之前就覺得computed計算屬性和直接在methods定義方法很類似,用computed可以實現的功能,直接定義方法好像基本都可以實現。

就像下面的簡單例子,做一個加法運算,computed計算屬性和methods的方法都是一樣的。

var vm = new Vue({
  el: '#app',
  data: {
    a: 1,
    b: 2
  },
  computed: {
    returnAdd: function () {
      return this.a + this.b;
    }
  },
  methods: {
    add: function () {
      return this.a + this.b;
    }
  }
})

如下圖,兩個運算都是沒問題的。

計算屬性是基於它們的響應式依賴進行緩存的。只在相關響應式依賴發生改變時它們才會重新求值。 

Vue官方文檔是這樣解釋的,計算屬性依賴於緩存,只要你的值沒有變,計算屬性都會返回之前緩存中的結果,適用一些需要進行大量計算的方法,如果不需要緩存,還是methods方便些。

1.2.computed計算屬性的setter

文檔后面還講到了計算屬性可以提供一個setter,就像下面這樣。

computed: {
    returnAdd: {
        // getter
        get: function() {
            this.sumAB_getter = this.a + this.b;
            return this.a + this.b;
        },
        // setter
        set: function(newVal) {
            console.log('returnAdd-setter:' + newVal);
            this.sumAB_setter = newVal;
        }
    }
},

我試了一下,getter會在returnAdd的值手動修改的時候觸發,但在計算后getter修改時不會觸發,目前也沒見別人用過,不是很清楚setter的用途。

 

2.Watch偵聽器

偵聽屬性Watch,當你有一些數據需要隨着其它數據變動而變動時,就可以使用Watch來監聽他們之間的變化。

2.1.簡單的watch偵聽

這里以上面的加法為例,使用watch做加法計算:

watch: {
    a: function(n, o){
        this.sumAB_watch = n + this.b;
        console.log('a-newValue:' + n, 'a-oldValue:' + o, 'sumAB_watch:' + this.sumAB_watch);
    },
    b: function(n, o){
        this.sumAB_watch = this.a + n;
        console.log('b-newValue:' + n, 'b-oldValue:' + o, 'sumAB_watch:' + this.sumAB_watch);
    },
},

監聽a和b的值,第一個參數是修改后的值,第二個參數是修改前的值,這樣就能監聽數據變化來做計算了。

不過這里還有個問題,就是頁面剛加載時,因為沒有變化,所以不會執行。

這里就引申出了另外的知識:handler方法和immediate屬性。

2.2.handler、immediate

其實之前寫的watch方法默認就是handler,而當immediate屬性為true時,就會先執行handler方法。

watch: {
    a: {
        handler(n, o){
            this.sumAB_watch = n + this.b;
            console.log('a-newValue:' + n, 'a-oldValue:' + o, 'sumAB_watch:' + this.sumAB_watch);
        },immediate: true
    },
    b: {
        handler(n, o){
            this.sumAB_watch = this.a + n;
            console.log('b-newValue:' + n, 'b-oldValue:' + o, 'sumAB_watch:' + this.sumAB_watch);
        },immediate: true
    }
},

這樣就會在頁面加載時先執行一次,如下圖。

2.3.監聽對象、數組等(deep屬性) 

在監聽對象時,會有一個問題,修改對象的值的時候,不會觸發handler方法。

數組則可以觸發,但是修改前的值和修改后的值是一樣的,這里我暫時不清楚是什么問題。

var vm = new Vue({
    el: '#app',
    data: {
        obj: {
            x: 10,
            y: 20
        },
        arr: [1, 2, 3, 4]
    },
    watch: {
        obj: {
            handler(n, o){
                console.log('obj-newValue:' + n, 'obj-oldValue:' + o,);
            }
        },
        arr: {
            handler(n, o){
                console.log('arr-newValue:' + n, 'arr-oldValue:' + o,);
            }
        }
    }
})

這里修改對象的值不會觸發。

 這時候就要用到deep屬性,設置deep屬性為true,監聽器就會深入觀察,向下遍歷,性能開銷可能會比較大。

obj: {
    handler(n, o){
        console.log('obj-newValue:' + JSON.stringify(n), 'obj-oldValue:' + JSON.stringify(o),);
    },
    deep: true
},

 這時候就能觀察到對象內的數據變化了。

這里還有遇到一個小問題,如果監聽器新增一個obj.z = obj.x + obj.y 的計算,這里監聽了整個obj的變化,這樣計算完成后,因為obj.z的變化,還會再執行一次,所以我覺得如果監聽了整個對象的話,計算結果還是不要寫到這個對象里面去,以免增加不必要的開銷。

 2.4.監聽字符串形式

如果不想監聽obj中其他值,只想監聽obj.x的值的變化,可以寫成字符串形式監聽。

'obj.x': {
    handler(n, o){
        console.log('obj.x-newValue:' + JSON.stringify(n), 'obj.x-oldValue:' + JSON.stringify(o),);
    }
},

2.5.監聽多個對象

有時一個值可能是根據多個對象中的值,共同計算出來的,可以把這些改變的值放到一個對象中去,也可以直接監聽多個對象。 

watch: {
    twoObj:{
        handler: function(val) {
            console.log('two change: ', val)
        },
        deep: true
    }
},
computed: {
    twoObj(){
        const { obj, obj2 } = this;
        return {
            obj,
            obj2
        }
    }
},

 這里是參考了 vue watch怎樣同時監聽兩個值的變化並執行方法 這篇文章。

以上就是我在寫關於監聽器的經驗和遇到問題,在這里簡單做下記錄,以后還可以多翻翻看,也希望對不懂的人有點小小的幫助。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM