vue watch 和 computed 區別與使用


computed 和 watch 的說明 與 區別

computed 計算屬性說明:

  • computed 是基於響應性依賴來進行緩存的。只有依賴數據發生改變,纔會從新進行計算(當觸發從新渲染,若依賴數據沒有改變,則 computed 不會從新計算)。若沒改變,計算屬性會當即返回以前緩存的計算結果。html

  • 不支持異步,當 computed 內有異步操做時無效,沒法監聽數據的變化的值。vue

  • computed 中的成員能夠只定義一個函數做爲只讀屬性, 也能夠定義成 get/set 變成可讀寫屬性api

  • 若是一個屬性是由其餘屬性計算而來的,這個屬性依賴其餘屬性,是一個多對一或者一對一,通常用 computed。數組

下面的計算屬性將再也不更新,由於 Date.now() 不是響應式依賴:緩存

computed: {
  now: function () {
    return Date.now()
  }
}

相比之下,每當觸發從新渲染時,調用方法將總會再次執行函數。frontend

咱們爲何須要緩存?假設咱們有一個性能開銷比較大的計算屬性 A,它須要遍歷一個巨大的數組並作大量的計算。而後咱們可能有其餘的計算屬性依賴於 A。若是沒有緩存,咱們將不可避免的屢次執行 A 的 getter!若是你不但願有緩存,請用方法來替代。異步

watch 監聽屬性說明:

  • 不支持緩存,數據變或者觸發從新渲染時,直接會觸發相應的操做。函數

  • watch 支持異步性能

  • 當一個屬性發生變化時,須要執行對應的操做;一對多時,通常用 watch。this

  • 監聽數據必須是 data 中聲明過或者父組件傳遞過來的 props 中的數據,當數據變化時,觸發其餘操做,函數有兩個參數,immediate:組件加載當即觸發回調函數執行,deep: 深度監聽,爲了發現對象內部值的變化,複雜類型的數據時使用,例如數組中的對象內容的改變,注意監聽數組的變更不須要這麼作。注意:deep 沒法監聽到數組的變更和對象的新增,參考 vue 數組變異,只有以響應式的方式觸發纔會被監聽到。

watch 和 computed 的區別是:

相同點:

  • 二者都是觀察頁面數據變化的。

不一樣點:

  • computed 只有當依賴的數據變化時纔會計算, 會緩存數據。
  • watch 每次都須要執行函數。watch 更適用於數據變化時的異步操做。

使用 參考官方文檔

computed 使用

  • 類型:{ [key: string]: Function | { get: Function, set: Function } }

  • 詳細:

計算屬性將被混入到 Vue 實例中。全部 getter 和 setter 的 this 上下文自動地綁定爲 Vue 實例。

注意若是你爲一個計算屬性使用了箭頭函數,則 this 不會指向這個組件的實例,不過你仍然能夠將其實例做爲函數的第一個參數來訪問。

computed: {
  aDouble: vm => vm.a * 2
}

計算屬性的結果會被緩存,除非依賴的響應式 property 變化纔會從新計算。注意,若是某個依賴 (好比非響應式 property) 在該實例範疇以外,則計算屬性是不會被更新的。

  • 示例:
var vm = new Vue({
    data: { a: 1 },
    computed: {
        // 僅讀取
        aDouble: function () {
            return this.a * 2
        },
        // 讀取和設置
        aPlus: {
            get: function () {
                return this.a + 1
            },
            set: function (v) {
                this.a = v - 1
            },
        },
    },
})
vm.aPlus // => 2
vm.aPlus = 3
vm.a // => 2
vm.aDouble // => 4

watch 使用 與 解釋

  • 類型:{ [key: string]: string | Function | Object | Array }

  • 詳細:

一個對象,鍵是須要觀察的表達式,值是對應回調函數。值也能夠是方法名,或者包含選項的對象。Vue 實例將會在實例化時調用 $watch(),遍歷 watch 對象的每個 property。

  • 示例:
var vm = new Vue({
    data: {
        a: 1,
        b: 2,
        c: 3,
        d: 4,
        e: {
            f: {
                g: 5,
            },
        },
    },
    watch: {
        a: function (val, oldVal) {
            console.log('new: %s, old: %s', val, oldVal)
        },
        // 方法名
        b: 'someMethod',
        // 該回調會在任何被偵聽的對象的 property 改變時被調用,不論其被嵌套多深
        c: {
            handler: function (val, oldVal) {
                ;/_ ... _/
            }, // or handler:'方法名'
            deep: true,
        },
        // 該回調將會在偵聽開始以後被當即調用
        d: {
            handler: 'someMethod', // or handler: function(val, oldVal){}
            immediate: true,
        },
        // 你能夠傳入回調數組,它們會被逐一調用
        e: [
            'handle1',
            function handle2(val, oldVal) {
                /* ... */
            },
            {
                handler: function handle3(val, oldVal) {
                    /* ... */
                },
                /* ... */
            },
        ],
        // watch vm.e.f's value: {g: 5}
        'e.f': function (val, oldVal) {
            ;/_ ... _/
        },
    },
})
vm.a = 2 // => new: 2, old: 1
  • 說明: 對應上方的 a~e

a: 監聽一個屬性,須要使用先後變化值時使用

b: 監聽一個屬性,不會使用到改變先後的值,只爲了執行一些方法,可使用字符串代替 字符串表明方法名

c: 在監聽一個對象時,當對象內部的屬性被改變時,沒法觸發 watch,設置 deep 爲 true 後,不管嵌套多深,只要屬性值被改變都會觸發監聽。但這種方式開銷會較大,監聽器會一層一層往下找,爲每一個屬性添加監聽器。

  • 若是咱們只是監聽對象的某個屬性改變時,能夠這樣作:
watch:{
        'user.name':{
            handler: 'method'
        }

    }

d: watch 是在監聽屬性改變時纔會觸發,組件建立時可能不會執行,所以咱們能夠設置 immediate: true,就會讓在組件建立後 watch 可以當即執行一次。就不用在 create 的時候去修改屬性啦。

  • handelr: 觸發監聽執行的方法(須要用到改變先後的值時,可換成函數)

  • immediate: 監聽開始以後被當即調用

e: 監聽一個屬性,執行多個函數包括回調等

注意,不該該使用箭頭函數來定義 watcher 函數 (例如 searchQuery: newValue => this.updateAutocomplete(newValue))。理由是箭頭函數綁定了父級做用域的上下文,因此 this 將不會按照指望指向 Vue 實例,this.updateAutocomplete 將是 undefined。

原文地址:http://book.levy.net.cn/doc/frontend/vue/vue_computed_watch.html

相關文章
相關標籤/搜索