模板內的表達式一般用於簡單的運算,當其過長或邏輯複復雜時,會變得難以維護vue
什麼是計算屬性
在Vue應用中,在模板中雙向綁定一些數據或者表達式,可是表達式若是過長,或者邏輯更爲複雜時,就會變得臃腫甚至難以維護和閱讀,好比
<div>
{{text.split(',').reverse().join(',')}}
</div>.
這裏表達式包含三個操做,並非很清晰,因此在遇到複雜的邏輯時應該使用計算屬性,上例能夠用計算屬性進行改寫:數組
<div id="CalculationProperties"> {{ReversedText}} </div> <script> var CalculationProperties = new Vue({ el: "#CalculationProperties", data: { text:"123,456", }, computed: { ReversedText: function () { //全部計算屬性都以函數的形式寫在Vue實例內的computed選項內,最終返回計算後的結果 return this.text.split(',').reverse().join(',') } } }) </script>
全部計算屬性都以函數的形式寫在Vue實例內的computed選項內,最終返回計算後的結果
計算屬性用法
在一個計算屬性裏能夠完成各類複雜的邏輯,包括邏輯運算、函數調用等,只要最終返回一個結果就能夠。除了上面的簡單的用法,計算屬性還能夠依賴多個vue實例的數據,只要其中人一個數據變化,計算屬性就會從新執行,視圖也會更新,例以下面的例子展現的是購物車內兩個包裹的物品總價緩存
<div id="prices"> 總價: {{prices}} </div> <script> // <!--購物車總價--> var prices = new Vue({ el: "#prices", data: { package1: [ { name: "華爲mate20pro", price: 4566, count: 2 }, { name: "華爲p30", price: 4166, count: 2 }, ], package2: [ { name: "蘋果", price: 30, count: 2 }, { name: "香蕉", price: 2, count: 20 }, ] }, computed: { prices: function () { var prices = 0; debugger for (var i = 0; i < this.package1.length; i++) { prices += this.package1[i].price * this.package1[i].count; } for (var i = 0; i < this.package2.length; i++) { prices += this.package2[i].price * this.package2[i].count; } return prices; } } }) </script>
當package1或package2中的商品發生變化,好比購買數量變化或者增刪商品時,計算屬性prices就會自動更新,視圖中的總價也會自動變化
每一個計算屬性都包含一個getter和setter,上面的例子都是計算屬性默認用法,只是利用了getter來讀取。在你須要時,也能夠提供一個setter函數,當手動修改計算屬性的值就像修改一個普通數據那樣,就會觸發setter函數,執行一些自定義的操做。app
<!--setter--> <div id="setter"> 姓名: {{fullName}} </div> <script> var setter = new Vue({ el: "setter", data: { firstName: 'Jack', lastName:'Green' }, 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[1]; } } } }) </script>
當執行 setter.fullName='Join Doe'時候,setter就會被調用,數據firstName和lastName都會相對更新,視圖一樣也會更新
絕大多狀況下,咱們只會使用默認的getter方法來讀取一個計算屬性,在業務中不多使用到setter,因此在聲明一個計算屬性的時候,能夠直接使用默認的寫法,沒必要將getter和setter都聲明
計算屬性除啦以上簡單的文本插值外,還常常用於動態的設置元素的樣式名稱class和內聯樣式style,當使用組件時,計算屬性也常常用來動態傳遞props之後,我會慢慢介紹到
計算屬性還有兩個很使用的小技巧很容易被忽略,一是計算屬性能夠依賴其餘計算屬性,二是計算屬性不只能夠依賴當前Vue實例的數據,還能夠依賴其餘Vue實例的數據函數
<div id="app1"></div> <div id="app2"> {{reversedText}} </div> <script> var app1 = new Vue({ el: "#app1", data: { text: "123,456" } }); var app2 = new Vue({ el: "#app2", computed: { reversedText: function () { //這裏是依賴app1實例中的數據text return app1.text.split(',').reverse().join(',') } } }) </script>
這裏咱們建立了兩個vue實例app1和app2,在app2的計算屬性reversedText中,依賴的是app1的數據text,因此當text變化時,實例app2的計算屬性也會變化,這樣的用法之後用到的也會比較多,尤爲是在多人協同開發時很經常使用,覺得你寫的組件所用到的數據須要依賴他人的組件提供,之後接觸的多了就會慢慢的意識到這一點。
計算屬性緩存
其實細心的話就會發現,調用methods裏的方法也能實現和計算屬性同樣的效果,甚至有的方法還能接收參數,使用起來更加的靈活,既然使用methods就能夠實現,那爲何還須要計算屬性呢?緣由就是計算屬性是基於他的依賴緩存的。一個計算屬性所依賴的數據發生變化時,他纔會從新取值,
因此依賴的text只要不改變。計算屬性也就不更新
computed:{
now:function()
{
return Date.now()
}
}
這裏的Date.now()不是響應式依賴,因此計算屬性now 不會更新,可是methods則不一樣,只要從新渲染他就會被調用,所以函數也會被執行。
使用計算屬性仍是methods取決於你是否須要緩存,當遍歷大數組和作大量計算時,應當使用計算屬性,除非你不但願獲得緩存this