咱們己經能夠搭建出一個簡單的 Vue 應用,在模板中雙向綁定一些數據或表達式了。可是表達式若是過長,或邏輯更爲複雜時,就會變得臃腫甚至難以閱讀和維護
舉例html
<div> {{ text.split ( ’,’ ) •reverse () . join (’,’)}} </div> 這裏的表達式包含 3 個操做,並非很清晰,因此在遇到複雜的邏輯時應該使用 計算屬性
。vue
全部的計算屬性都以函數的形式寫在 Vue 實例內的computed 選項內,在一個計算屬性裏能夠完成各類複雜的邏輯,包括運算、函數調用等,只要最終返回計算後的結果npm
計算屬性還能夠依賴多個 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/vue@2.5.16/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來讀取 , 當手動修改計算屬性的值就像修改一個普通數據那樣時,就會觸發 set
ter函數,執行一些自定義的操做緩存
計算屬性除了上述簡單的文本插值外,還常常用於動態地設置元素的樣式名稱 class 和內聯樣式 styleapp
<!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/vue@2.5.16/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>
修改fullname值得時候,就會調用set函數
iphone
調用 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/vue@2.5.16/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調用的計算屬性的值從新更新了,但計算屬性的沒有變
ui
結論: 沒有使用計算屬性,在 methods 裏定義了一個方法實現了相同的效果,甚至該方法還能夠接受
參數,使用起來更靈活。既然使用 methods 就能夠實現,那麼爲何還須要計算屬性呢?
緣由就是
計算屬性是基於它的依賴緩存的。 一個計算屬性所依賴的數據發生變化時,它纔會從新取值什麼時候使用: -----------使用計算屬性仍是 methods 取決於你是否須要緩存,當遍歷大數組和作大量計算時,應當使用計算屬性,除非你不但願獲得緩存