vue中的計算屬性和偵聽器

計算屬性概念

模板內的表達式很是便利,可是設計它們的初衷是用於簡單運算的。在模板中放入太多的邏輯會讓模板太重且難以維護。例如:html

<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

在這個地方,模板再也不是簡單的聲明式邏輯。你必須看一段時間才能意識到,這裏是想要顯示變量 message 的翻轉字符串。當你想要在模板中屢次引用此處的翻轉字符串時,就會更加難以處理。vue

因此,對於任何複雜邏輯,你都應當使用計算屬性

簡單的理解爲:數組

1.計算屬性其實就是 Vue 實例的一個屬性

2.計算屬性通常依賴傳統的 Vue 實例屬性

3.計算屬性通常是經過運算獲得的屬性
緩存

計算屬性的get和set

簡單的寫法app

computed: {
  reversedMessage() {
    return this.message.split('').reverse().join('')
  }
}

完整版寫法異步

computed: {
    reversedMessage: {
        get() { //獲取值
           return this.message.split('').reverse().join('')
        },
        set(val) { // set方法:設置值
         this.message = val.split('').reverse().join('')
        }
    }
}
計算屬性VS方法

HTMLide

<p>Reversed message: "{{ reversedMessage() }}"</p>

JS函數

// 在組件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

計算屬性是基於它們的依賴進行緩存的,只有在它相關的依賴發生改變時纔會從新求值,即計算屬性會對計算出來的結果進行緩存,這就意味着只要 message 尚未發生改變,屢次訪問 reversedMessage 計算屬性會當即返回以前的計算結果,而沒必要再次執行函數
性能

方法是每次從新渲染時,調用方法將總會再次執行函數,開銷比較大ui

咱們爲何須要緩存?

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

watch
放在 data 中的對象,一旦發生改變就會執行相應的操做,當須要在數據變化時執行異步或開銷較大的操做時,這個方式是最有用的

<div>
  <p>FullName: {{fullName}}</p>
  <p>FirstName: <input type="text" v-model="firstName"></p>
</div>
new Vue({
  el: '#root',
  data: {
    firstName: 'Joy',
    lastName: 'lqy',
    fullName: ''
  },
  watch: {
    firstName(newName, oldName) {
      this.fullName = newName + ' ' + this.lastName;
    }
  } 
})

watch 中的對象在 data 中已經定義了,當咱們輸入firstName後, watch監聽每次修改變化的新值,而後計算輸出fullName。也就是上面的代碼中,fullName 一開始被渲染出來的時候是空值,以下所示:

watch的高級用法

handler方法和immediate屬性

如上所述,一開始被渲染出來的時候,fullName是空值,若是想要一開始就讓最初綁定的值執行該怎麼辦尼?別急,咱們只須要給firstName綁定一個handler方法,以前咱們寫的watch方法其實默認寫的就是這個handler,Vue.js會去處理這個邏輯,最終編譯出來其實就只這個handler,設置immediate:true表明若是在 wacth 裏聲明瞭 firstName 以後,就會當即先去執行裏面的handler方法,若是爲 false就跟咱們之前的效果同樣,不會在綁定的時候就執行

修改後的代碼以下:

watch: {
    firstName: {
        handler(newName, oldName) {
            this.fullName = newName + ' ' + this.lastName;
        },
        // 表明在wacth裏聲明瞭firstName這個方法以後當即先去執行handler方法
        immediate: true
    }
}

結果以下:

deep屬性

deep,默認值爲false,表明是否深度監聽,

總的來講,計算屬性傾向于格式化/處理當前的數據,而 watch 傾向於執行數據變化須要進行的操做

註銷watch

爲何要註銷 watch?由於咱們的組件是常常要被銷燬的,好比咱們跳一個路由,從一個頁面跳到另一個頁面,那麼原來的頁面的 watch 其實就沒用了,這時候咱們應該註銷掉原來頁面的 watch 的,否則的話可能會致使內置溢出。好在咱們平時 watch 都是寫在組件的選項中的,他會隨着組件的銷燬而銷燬。

const app = new Vue({
  template: '<div id="root">{{text}}</div>',
  data: {
    text: 0
  },
  watch: {
    text(newVal, oldVal){
      console.log(`${newVal} : ${oldVal}`);
    }
  }
});

可是,若是咱們使用下面這樣的方式寫 watch,那麼就要手動註銷了,這種註銷其實也很簡單

const unWatch = app.$watch('text', (newVal, oldVal) => {
  console.log(`${newVal} : ${oldVal}`);
})
unWatch(); // 手動註銷watch

app.$watch調用後會返回一個值,就是unWatch方法,你要註銷 watch 只要調用unWatch方法就能夠了。

參考

計算屬性和偵聽器
Vue.js中偵聽器(watch)的高級用法

相關文章
相關標籤/搜索