一、使用計算屬性的原因
我們己經可以搭建出一個簡單的 Vue 應用,在模板中雙向綁定一些數據或表達式了。但是表達式如果過長,或邏輯更爲複雜時,就會變得臃腫甚至難以閱讀和維護
舉例
<div>
{{ text.split ( ’,’ ) •reverse () . join (’,’)}}
</div>
這裏的表達式包含 3 個操作,並不是很清晰,所以在遇到複雜的邏輯時應該使用 計算屬性
。
二、 計算屬性用法
所有的計算屬性都以函數的形式寫在 Vue 實例內的computed 選項內,在一個計算屬性裏可以完成各種複雜的邏輯,包括運算、函數調用等,只要最終返回計算後的結果
計算屬性還可以依賴多個 Vue 實例的數據,只要其中任一數據變化,計算屬性就會重新執行,視圖也會更新
小技巧: 計算屬性還有兩個很實用的小技巧容易被忽略:
一是計算屬性可以依賴其他計算屬性:
二是計算屬性不僅可以依賴當前 Vue 實例的數據,還可以依賴其他實例的數據
實例 :展示兩個購物車的物品總價
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="demo">
{{prices}}
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
var app2 =new Vue({
el:'#abc',
data:{
msg:'ssssssfffff'
}
})
var app1 =new Vue({
el:'#demo',
data:{
package1:[
{
name:'iphone8',price:6999,count:3
},
{
name:'ipad',price:3600,count:6
}
],
package2:[
{
name:'iphone8',price:6999,count:3
},
{
name:'ipad',price:3600,count:6
}
]
},
computed:{
prices:function(){ //不定義的話,默認是getter函數
var prices=0;
for(var i=0;i<this.package1.length;i++){
prices =prices+ this.package1[i].price *this.package1[i].count
}
for(var j=0;j<this.package2.length;j++){
prices +=this.package2[j].price * this.package2[j].count
}
return prices+'-------'+app2.msg //定義msg是代表計算屬性可以依賴多個vue實例的數據
}
}
})
</script>
</body>
</html>
三、getter和setter
每一個計算屬性都包含一個 getter 和一個 setter函數!
默認手法是getter來讀取 , 當手動修改計算屬性的值就像修改一個普通數據那樣時,就會觸發 set
ter函數,執行一些自定義的操作
計算屬性除了上述簡單的文本插值外,還經常用於動態地設置元素的樣式名稱 class 和內聯樣式 style
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="abc">
my name is {{fullName}}<hr>
my name is {{firstName}}{{lastName}}<hr>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
var app2 =new Vue({
el:'#abc',
data:{
firstName:'zhang',
lastName:'sanfeng'
},
computed:{
//計算屬性的默認用法是getter函數
// fullName:function(){
// return this.firstName+''+this.lastName
// }
fullName:{
get:function(){
return this.firstName+''+this.lastName
},
set:function(newValue){
console.log('我是set方法,我被調用了')
var names=newValue.split(',')//分割成數組
this.firstName=names[0]
this.lastName=names[1]
}
}
}
})
</script>
</body>
</html>
四、計算屬性的緩存
調用 methods 裏的方法也可以與計算屬性起到同樣的作用
頁面中的方法: 如果是調用方法,只要頁面重新渲染,方法就會重新執行。不需要渲染,則不需要重新執行
計算屬性:不管渲染不渲染,只要計算屬性依賴的數據未發生變化,就永遠不變
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="demo">
{{text}}<br>
{{text.split(',').reverse().join(',')}}<hr>
{{reverseText}}<hr>
計算屬性的緩存
{{now}}<hr>
通過methods拿到時間戳(方法需要加括號)
{{thisTime()}}
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
//需求是把123,456,789編程789,456,123
var app =new Vue({
el:'#demo',
data:{
text:'123,456,789'
},
computed:{
reverseText:function(){
return this.text.split(',').reverse().join(',');
//由於文本取值只能用單行表達式,邏輯過程就會變得臃腫,所以遇到複雜的邏輯時,應當使用計算屬性。
//計算屬性可以用多行表達式,運算和函數調用等,
},
now:function (){
return Date.now()
}
},
methods:{
thisTime:function(){
return Date.now()
}
}
})
</script>
</body>
</html>
當我們改變text 的值,頁面重新渲染,所以通過methods調用的計算屬性的值重新更新了,但計算屬性的沒有變
結論: 沒有使用計算屬性,在 methods 裏定義了一個方法實現了相同的效果,甚至該方法還可以接受
參數,使用起來更靈活。既然使用 methods 就可以實現,那麼爲什麼還需要計算屬性呢?
原因就是
計算屬性是基於它的依賴緩存的。 一個計算屬性所依賴的數據發生變化時,它纔會重新取值
何時使用: -----------使用計算屬性還是 methods 取決於你是否需要緩存,當遍歷大數組和做大量計算時,應當使用計算屬性,除非你不希望得到緩存