計(jì)算屬性
雙括弧的模板表達(dá)式是很便利的唧瘾,但是當(dāng)初設(shè)計(jì)他只是用來(lái)做簡(jiǎn)單的運(yùn)算,如果在模板中放入大量的邏輯缨该,會(huì)讓模板過(guò)重偎行,并且不好維護(hù)。
如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
這里是修改了message的內(nèi)容贰拿,雖然這樣寫(xiě)也可以蛤袒,但是有點(diǎn)違反了當(dāng)初模板語(yǔ)法的設(shè)計(jì)思路,不推薦膨更。
對(duì)于任何比較復(fù)雜的邏輯汗盘,推薦使用 計(jì)算屬性。
<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: {
// 計(jì)算屬性的 getter
reversedMessage: function () {
// `this` 指向 vm 實(shí)例
return this.message.split('').reverse().join('')
}
}
})
這里我們聲明了一個(gè)計(jì)算屬性 reversedMessage
询一。我們提供的函數(shù)將用作屬性 vm.reversedMessage
的 getter
函數(shù)
reversedMessage
最后得到方法返回的修改過(guò)的值,插入到模板語(yǔ)法處隐孽。這也是響應(yīng)式的,只要原來(lái)的message修改健蕊,就會(huì)觸發(fā)計(jì)算屬性菱阵。
計(jì)算屬性緩存 vs 方法
剛才提到的 顛倒message的處理,我們通過(guò)methods中調(diào)用方法也一樣可以做到缩功。
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在組件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
我們可以將同一函數(shù)定義為一個(gè)方法而不是一個(gè)計(jì)算屬性晴及。兩種方式的最終結(jié)果確實(shí)是完全相同的。
不同的地方是嫡锌,計(jì)算屬性是基于他們之間的依賴(lài)進(jìn)行緩存的虑稼,只有在依賴(lài)關(guān)系或者值發(fā)生改變的時(shí)候才會(huì)重新請(qǐng)求,這就意味著只要 message
還沒(méi)有發(fā)生改變势木,多次訪問(wèn) reversedMessage
計(jì)算屬性會(huì)立即返回之前的計(jì)算結(jié)果蛛倦,而不必再次執(zhí)行函數(shù)。
這樣效率和性能也更加高啦桌,而且不需要手動(dòng)觸發(fā)溯壶。
相比方法,每次重新渲染甫男,調(diào)用的方法總會(huì)執(zhí)行的且改。
我們?yōu)槭裁葱枰彺妫考僭O(shè)我們有一個(gè)性能開(kāi)銷(xiāo)比較大的計(jì)算屬性 A板驳,它需要遍歷一個(gè)巨大的數(shù)組并做大量的計(jì)算又跛。然后我們可能有其他的計(jì)算屬性依賴(lài)于 A 。如果沒(méi)有緩存若治,我們將不可避免的多次執(zhí)行 A 的 getter慨蓝!如果你不希望有緩存感混,請(qǐng)用方法來(lái)替代。
計(jì)算屬性 vs 監(jiān)聽(tīng)屬性
Vue提供了一種更通用的方式來(lái)觀察和響應(yīng)Vue實(shí)例上的數(shù)據(jù)變動(dòng)菌仁,監(jiān)聽(tīng)屬性,當(dāng)你的部分?jǐn)?shù)據(jù)需要隨著其他數(shù)據(jù)的變動(dòng)而變動(dòng)時(shí)静暂,可容易 濫用watch
济丘,特別是如果你之前使用過(guò) angular,通常更好的方法是使用計(jì)算屬性洽蛀,而不是命令形式的 watch 回調(diào)摹迷。
div id="demo">{{ fullName }}</div>
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
}
}
})
上面代碼是命令式且重復(fù)的,他通過(guò)監(jiān)聽(tīng)2個(gè)值的變化來(lái)重新渲染新的值。將它與計(jì)算屬性的版本進(jìn)行比較:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
計(jì)算屬性的setter
計(jì)算屬性默認(rèn)只有 getter郊供,不過(guò)如果需要峡碉,可以添加一個(gè) setter
// ...
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]
}
}
}
//
監(jiān)聽(tīng)器
雖然計(jì)算屬性在大多數(shù)情況下都比較合適,但有時(shí)候也是需要一個(gè)自定義的監(jiān)聽(tīng)器驮审。這就是為什么vue通過(guò) watch 選項(xiàng)提供了一個(gè)更加通用的方法來(lái)響應(yīng)數(shù)據(jù)的變化鲫寄。當(dāng)需要在數(shù)據(jù)變化時(shí)執(zhí)行異步或者開(kāi)銷(xiāo)較大的操作時(shí),這個(gè)時(shí)候使用 watch 是最有用的疯淫。
除了 watch
選項(xiàng)之外地来,您還可以使用命令式的 vm.$watch API。