Vue.js 學習旅程Mile 11 – Computed 計算屬性篇


Posted by yuhantaiwan on 2020-05-17

基本用法

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // a computed getter
    reversedMessage: function () {
      // `this` points to the vm instance
      return this.message.split('').reverse().join('')
    }
  }
})

computed 內的 reversedMessage function 就是一個 getter method,每當 message 的值有變化時,便重新計算把值存回 reversedMessage

計算屬性特性

具 function 運算能力 的 data 屬性

  • 每個對應的計算屬性都是一個具有回傳值且沒有傳入參數的 function 。
  • 在模板中直接以 function 名稱設置,不用加 ( )

跟著來源資料變化

  • 這個來源資料之一必要是來自 Vue 實例內的 data,才能做響應式依賴。
  • 資料變動時,掃 virtual DOM,看哪裡需要更動做修改。
  • 沒有 DOM 就沒有 virtual DOM,有 DOM 資料才能做連動。

將結果暫存

  • 有暫存機制(cache),若來源資料沒有變化的話,便不會執行方法。

getter & setter

computed 預設只有 getter 屬性,但也可以經由以下方法重設 setter 屬性。

<div id="app">
  <p>fullName (computed):{{ fullName }}</p>
</div>
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

當再次運行 vm.fullName = 'John Doe' 時,setter 會被調用,vm.firstName 和 vm.lastName 也會相對應地被更新。

更多關於 getter 和 setter 的知識可以參考這篇文章:那些關於 Vue 的小細節 - Computed 中 getter 和 setter 觸發的時間點

與 Methods 的不同

使用 methods 改寫上例,也能得到相同的效果。

<p>Reversed message: "{{ reverseMessage() }}"</p>
methods: {
  reverseMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

不同的是,computed 是根據相依的資料改變時才做計算,而 method 是不管有無相依都會計算,只要每次重新渲染畫面就會執行一次。

使用 Date.now() 的陷阱

<div id="app">
  <p>message:{{ message }}</p>
  <p>now (computed):{{ now }}</p>
  <p>getNow (method):{{ getNow() }}</p>
</div>
var vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello World!',
  },
  computed: {
    now: function() {
      return Date.now();
    },
  },
  methods: {
    getNow: function() {
      return Date.now();
    },
  },
});

在一開始都會執行 computed 和 methods 的時候,沒有任何差異。

當改變 message 時,由於 now 這個計算屬性沒有用到任何相依的資料,因此不重新計算取值;但 getNow 是方法,無論是否有相依,只要有變動都會重新計算。

與 Watch 的不同

<div id="demo">{{ fullName }}</div>

使用 watch

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

使用 computed

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

使用 watch:多了一個 fullName 屬性,而且其相依的屬性有幾個,就得多幾個 watcher 監聽。

使用 computed 時機

  • 需要資料產生資料時
  • 為了達到更好效能,不需要每次更新方法時

參考資料


#w3HexSchool #Vue #javascript







Related Posts

[Day 03] 觀察者模式,命令模式,轉接器模式,表象模式

[Day 03] 觀察者模式,命令模式,轉接器模式,表象模式

Chrome 83 DevTools 新功能:切換 location 與 locales

Chrome 83 DevTools 新功能:切換 location 與 locales

Nengo AI 入門

Nengo AI 入門



Comments