基本用法
<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 時機
- 需要資料產生資料時
- 為了達到更好效能,不需要每次更新方法時