1. 計算屬性的定義
計算屬性是vue實例中的一個配置選項:computed
所有的計算屬性都以函數(shù)的形式寫在vue實例內(nèi)的computed選項內(nèi),最終返回計算后的結(jié)果。其依賴的數(shù)據(jù)變化才變化。
每一個計算屬性都包含一個 getter 方法和一個 setter 方法。
(1)讀取計算屬性的值 , 默認(rèn)調(diào)用方法getter方法
(2)當(dāng)數(shù)據(jù)改變時,默認(rèn)調(diào)用set方法
computed的屬性可以被視為是 data 一樣,可以讀取和設(shè)值
需要注意的是融蹂,不是說我們更改了getter里使用的變量,就會觸發(fā)computed的更新弄企,前提是computed里的值必須要在模板里使用才行超燃。
說明
當(dāng)一些數(shù)據(jù)需要根據(jù)其它數(shù)據(jù)變化時,需要進(jìn)行處理才能去展示,雖然vue提供了綁定數(shù)據(jù)表達(dá)式綁定的方式,但是設(shè)計它的初衷只是用于簡單運算的。在模板中放入太多的邏輯會讓模板過重且難以維護,對于一些比較復(fù)雜和特殊的計算有可能就捉襟見肘了,而且計算的屬性寫在模板里也不利于項目維護
computed主要的作用:
分離邏輯(模板和數(shù)據(jù)分離)
緩存值
雙向綁定(getter,setter)
2.計算屬性的基礎(chǔ)用法
在一個計算屬性里可以完成各種復(fù)雜的邏輯拘领,包括運算意乓、函數(shù)調(diào)用等,通常里面都是一個個計算相關(guān)的函數(shù) , 一般就是用來通過其他的數(shù)據(jù)算出一個新數(shù)據(jù) , 只要最終返回一個計算出來的結(jié)果即可约素。
計算屬性后面直接跟一個 function届良,使用計算屬性的默認(rèn)方法 getter 來讀取,里面可以執(zhí)行一些邏輯或者直接return返回的值
// 默認(rèn)用法 getter 舉例:
computed: {
prices: function(){
var prices = 0
for(let i=0; i<this.package.length; i++){
prices += this.package[i].price * this.package[i].count
}
return prices
},
fullName: function(){ // 直接return
return this.firstName + '-' + this.lastName
},
// 上面寫法等同于
fullname: {
get: function(){
return this.firstname + '-' + this.lastname
},
}
需要時,也可以提供一個 setter 函數(shù) 圣猎, 當(dāng)手動修改計算屬性的值就像修改一個普通數(shù)據(jù)那樣時士葫,就會觸發(fā) setter函數(shù),執(zhí)行一些自定義的操作 送悔。例如下顯示全名慢显。
// setter 用法 舉例:
var App = new Vue({
el: '#naa',
data: {
firstName: 'Jay',
lastName: 'Chou'
},
computed: {
fullName: {
// 數(shù)據(jù)渲染時會自動調(diào)用get方法
get: function(){
return this.firstName + '-' + this.lastName
},
// 注意必須要傳遞參數(shù),否則沒有意義
// 數(shù)據(jù)變化時自動調(diào)用set方法
set: function(newValue){
var names = newValue.split('-')
this.firstName = names[0]
this.lastName = names[1]
}
}
}
})
fullname = 'Jay-Chou' // 此時會調(diào)用set方法
若現(xiàn)在再運行 vm.fullName = 'John Doe' 時爪模,setter 會被調(diào)用,vm.firstName 和 vm.lastName也會相應(yīng)地被更新荚藻;進(jìn)而會觸發(fā)getter被調(diào)用屋灌。
// 延伸
可以點擊事件觸發(fā)seterr函數(shù)
<input type='text' v-model='textValue'>
//使用計算屬性
{{reverseMessage}}
// 觸發(fā)setter
<button @click='computedSet(textValue)'>set</button>
計算屬性
computed{
reverseMessage:{
get:function(){
return this.textValue.split('').reverse().jion('')
},
set:function(message){
this.textValue = message + 'HELLO'
}
}
},
methods:{
computedSet(message){
this.reverseMessage = message
}
}
注意
絕大多數(shù)情況下,我們只會用默認(rèn)的getter方法來讀取一個計算屬性应狱,在業(yè)務(wù)中很少用到setter,所以在聲明一個計算屬性時共郭,可以直接使用默認(rèn)的寫法
3.計算屬性的高級用法
1.計算屬性還可以依賴多個vue實例的數(shù)據(jù),只要其中任一個數(shù)據(jù)變化疾呻,計算屬性就會重新執(zhí)行除嘹,視圖也會更新。適用于比較費時的數(shù)據(jù)計算
2.當(dāng)使用組件時岸蜗,計算屬性也經(jīng)常用來 動態(tài)傳遞props尉咕。
小技巧
計算屬性還有兩個很實用的小技巧容易被忽略:
- 計算屬性可以依賴其他計算屬性;
- 計算屬性不僅可以依賴當(dāng)前 Vue 實例的數(shù)據(jù)散吵,還可以依賴其他實例的數(shù)據(jù)。
4.計算屬性的緩存
計算屬性基于它們的依賴進(jìn)行緩存的蟆肆,只有相關(guān)依賴發(fā)生改變的時候才會重新求值矾睦,一般為響應(yīng)式依賴
什么是響應(yīng)式依賴,Vue 不能檢測到對象屬性的添加或刪除炎功。由于 Vue 會在初始化實例時對屬性執(zhí)行 getter/setter 轉(zhuǎn)化過程枚冗,所以屬性必須在 data 對象上存在才能讓 Vue 轉(zhuǎn)換它,這樣才能讓它是響應(yīng)
vue提供cache標(biāo)識 , 設(shè)置cache為false可以關(guān)閉緩存
5.計算屬性與methods的區(qū)別
計算屬性一般就是用來通過其他的數(shù)據(jù)算出一個新數(shù)據(jù)蛇损,而且它有一個好處就是赁温,它把新的數(shù)據(jù)緩存下來了,當(dāng)其他的依賴數(shù)據(jù)沒有發(fā)生改變淤齐,它調(diào)用的是緩存的數(shù)據(jù)股囊,這就極大的提高了我們程序的性能。而如果寫在methods里更啄,數(shù)據(jù)根本沒有緩存的概念稚疹,頁面每渲染一次就重新執(zhí)行,所以每次都會重新計算。
共同點
調(diào)用 methods 里的方法也可以與計算屬性起到同樣的作用祭务。
區(qū)別
方法methods : 如果是調(diào)用方法内狗,只要頁面重新渲染,方法就會重新執(zhí)行义锥;若不需要渲染柳沙,則不需要重新執(zhí)行。
計算屬性computed:不管是否渲染拌倍,只要計算屬性依賴的數(shù)據(jù)(緩存)未發(fā)生變化赂鲤,就永遠(yuǎn)不變噪径。
( 計算屬性緩存是定義在計算屬性 computed 里的。)
結(jié)論
(1)用計算屬性可以實現(xiàn)的問題蛤袒,在 methods 里定義一個方法也可以實現(xiàn)相同的效果熄云,甚至該方法還可以接受參數(shù),使用起來更靈活妙真。
(2)既然使用 methods 就可以實現(xiàn)缴允,那么為什么還需要計算屬性呢?因為計算屬性是基于它的依賴緩存的珍德,一個計算屬性所依賴的數(shù)據(jù)發(fā)生變化時练般,它才會重新取值,所以只要依賴的數(shù)據(jù)不改變锈候,計算屬性也就不更新薄料。
何時使用二者
使用計算屬性還是 methods 取決于是否需要緩存,當(dāng)遍歷大數(shù)組和做大量計算時泵琳,應(yīng)當(dāng)使用計算屬性摄职,除非不希望得到緩存;
當(dāng)需要數(shù)據(jù)實時發(fā)生變化時获列,適合用 methods谷市。
6.計算屬性與watch的區(qū)別
1.觸發(fā)條件不同
computed計算屬性會依賴于使用它的data屬性,只要是依賴的data屬性值有變動击孩,則自定義重新調(diào)用計算屬性執(zhí)行一次迫悠。
watch則是在監(jiān)控的data屬性值發(fā)生變動時,其會自動調(diào)用watch回調(diào)函數(shù)巩梢。
2.應(yīng)用場景不同
執(zhí)行異步操作创泄,開銷較大的操作,避免堵塞主線程括蝠,使用watch鞠抑。
簡單且串行返回的,使用computed
參考文章
http://www.reibang.com/p/6a1a4b61a7f6
http://www.reibang.com/p/56f337688d6b
具體應(yīng)用
// 觀察outerNext的變化,控制按鈕是否禁止或啟用
<div class="verify-btn">
<button @click="goToNext" :class="{opacity :!outerNext}" :disabled="!outerNext">下一步</button>
</div>
computed: {
outerNext() {
if(this.secondObj.TransAmt != '' && this.secondObj.TransType != '2') {
return true;
} else if(this.secondObj.TransType == '2' && this.secondObj.TransAmt != '') {
if(this.secondObj.BespokeType == '0' && this.secondObj.BespokeDate != '') {
return true;
} else if(this.secondObj.BespokeCycleType == '0' || this.secondObj.BespokeCycleType == '1') {
if(this.secondObj.BespokeCycle != '' && this.secondObj.BespokeBeginDate != '' && this.secondObj.BespokeEndDat != '') {
return true;
}
}
}
return false;
},
},
// computed也可以跟watch一樣,檢測data中某個數(shù)據(jù)的變化,如果數(shù)據(jù)發(fā)生變化,可以默認(rèn)調(diào)用getter函數(shù)拿到變化后的新數(shù)據(jù)
// 例如 , 需要檢測data中PayeeType數(shù)據(jù)的變化 (點擊單選框切換個人和企業(yè)兩個按鈕)
<div>
<span>收款人類型</span>
// 在vant中通過v-model綁定值當(dāng)前選中項的 name
<van-radio-group v-model="interThirdObj.PayeeType" @click.native="Sta">
<van-radio name="1" class="left-radio" checked-color="#009E96">企業(yè)</van-radio>
<van-radio name="0" checked-color="#009E96">個人</van-radio>
</van-radio-group>
</div>
interThirdObj:{
PayeeType: '1', //收款人類型 0-個人 1-企業(yè)
}
// 可以如下實現(xiàn)
computed: {
PayeeType() {
return this.interThirdObj.PayeeType
}
}
// 這樣可以拿到切換后的新值
// 需要注意 , 并不一定是在模板字符串使用了data中的數(shù)據(jù)才需要computed ,
// 需要檢測某個數(shù)據(jù)的變化就可以使用 , 它跟watch的作用類似 ,
// 區(qū)別在于watch是不斷觸發(fā)更新 , 而computed只有值更新后才觸發(fā)一次