一般, 咱們是在模板中, 經過插值語法顯示data的內容, 但有時候咱們可能須要在{{}}
裏添加一些計算, 而後在展現出來數據. 這時咱們能夠使用到計算屬性html
先來舉個例子, 好比: 一個班, 有幾個學生參加期末考試, 要計算考試的平均分. 咱們來看看, 一般要怎麼作?vue
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app">考試成績 <ul> <li v-for="stu in students">{{stu.name}} -- {{stu.score}}</li> </ul> <p>平均分: <label>{{getAvg()}}</label></p> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: "#app", data: { message:"班級考試平均分", students: [ {name:"張三", score:90}, {name:"lisi", score:100}, {name:"wangwu", score:99}, {name:"zhaoliu", score:89}, {name:"liuqi", score:95} ] }, methods: { getAvg() { let sum = 0; for (let i = 0; i < this.students.length; i++) { console.log(this.students[i].score); let stu = this.students[i]; sum += stu.score; } console.log("平均分:" + sum/this.students.length); return sum/this.students.length; } } }) </script> </body> </html>
咱們定義了一組學生的成績. 而後將其顯示在頁面上, 而後經過方法getAvg計算平均分. 緩存
這裏咱們在獲取平均分的時候, 使用的是{{getAve()}} 其實, 平均分咱們理解更像是一個屬性, 而不是一個方法. 爲了方便計算, vue給咱們提供了一個computed屬性, 專門用來作計算. computed中定義的也是方法, 這個方法的方法名一般都定義爲名詞. 咱們來看一下使用app
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app">考試成績 <ul> <li v-for="stu in students">{{stu.name}} -- {{stu.score}}</li> </ul> <p>平均分: <label>{{avg}}</label></p> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: "#app", data: { message:"班級考試平均分", students: [ {name:"zhangsan", score:90}, {name:"lisi", score:100}, {name:"wangwu", score:99}, {name:"zhaoliu", score:89}, {name:"liuqi", score:95} ] }, computed: { avg: function() { let sum = 0; for (let i = 0; i < this.students.length; i++) { console.log(this.students[i].score); let stu = this.students[i]; sum += stu.score; } console.log("平均分:" + sum/this.students.length); return sum/this.students.length; } }, methods: { } }) </script> </body> </html>
這裏,增長了一個computed屬性, 裏面定義了avg方法, 沒錯, 本質仍是方法, 但命名的時候, 將其命名爲名詞.函數
眼尖的同窗應該已經發現了, 這好像和methods方法同樣啊, 就是換了個名字. 那computed計算屬性和methods方法有什麼區別呢?this
咱們用案例來講明他們之間的區別. spa
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <p> Origin Message: {{message}}</p> <p>Mthod Message:{{getMessage()}}</p> <p>Mthod Grade:{{getGrade()}}</p> <p>Mthod Class:{{getClass()}}</p> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: "#app", data: { message:"班級考試平均分", className: "1班", gradeName:"一年級" }, methods: { getGrade: function(){ console.log("調用Grade計算") return "方法" + this.gradeName }, getClass: function(){ console.log("調用class計算") return "方法" + this.className }, getMessage: function(){ console.log("調用message計算") return "方法" + this.message } } }) </script> </body> </html>
咱們發現, 在修改一個屬性, 其餘屬性都沒變化的狀況下, 咱們發現methods裏的方法都被執行了一遍code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <p> Origin Message: {{message}}</p> <p>Mthod Message:{{getMessage}}</p> <p>Mthod Grade:{{getGrade}}</p> <p>Mthod Class:{{getClass}}</p> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: "#app", data: { message:"班級考試平均分", className: "1班", gradeName:"一年級" }, computed: { getGrade: function(){ console.log("調用Grade計算") return "方法" + this.gradeName }, getClass: function(){ console.log("調用class計算") return "方法" + this.className }, getMessage: function(){ console.log("調用message計算") return "方法" + this.message } } }) </script> </body> </html>
控制檯輸出htm
咱們發現, 當控制檯修改其中一個屬性值, 只有調用這個屬性的方法會從新執行對象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <p>調用方法</p> <p>{{getMes()}}</p> <p>{{getMes()}}</p> <p>{{getMes()}}</p> <p>{{getMes()}}</p> <p>調用計算屬性</p> <p>{{mes}}</p> <p>{{mes}}</p> <p>{{mes}}</p> <p>{{mes}}</p> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: "#app", data: { firstName: "Elon", lastName: "Musk" }, computed: { mes: function(){ console.log("調用計算屬性") return this.firstName + " " + this.lastName } }, methods: { getMes: function(){ console.log("調用method方法") return this.firstName + " " + this.lastName } } }) </script> </body> </html>
這是兩種方式的調用, 可是結果都同樣, 都是打印輸出姓名, 計算屬性mes調用了四次, 方法getMes()也調用了四次, 咱們來看看運行結果
兩次打印的結果是同樣的, 可是調用getMes()調用了4次, 而mes計算屬性只計算了一次.
因此,官網說,對於任何複雜邏輯,都應當使用計算屬性。
問題: 咱們發現, 在計算屬性和methods方法調用的是偶還有一點不一樣, 那就是調用方式不一樣. method方調用是{{getMessage()}}, 而計算屬性是{{getMessage}}, 咱們上面不是說計算屬性中定義的也是方法麼? 爲何不須要使用()呢? 下面來研究一下
仍是這個案例, 咱們來看看代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app">{{message}} {{avg}}</div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { message: "計算平均分:", students: [ {name:"zhangsan", score:90}, {name:"lisi", score:100}, {name:"wangwu", score:99}, {name:"zhaoliu", score:89}, {name:"liuqi", score:95} ] }, computed: { avg: function() { let sum = 0; for (let i = 0; i < this.students.length; i++) { console.log(this.students[i].score); let stu = this.students[i]; sum += stu.score; } console.log("平均分:" + sum/this.students.length); return sum/this.students.length; } } }); </script> </body> </html>
咱們在計算平均分的時候, 是把avg當作一個屬性來對待的, 因此,調用的時候這麼寫{{avg}}, 而不是{{avg()}}. 可是咱們定義的時候倒是給定義成方法了, 爲何會這樣呢?
下面咱們來研究computed完整的寫法, 研究完這個, 就知道爲何這麼寫了.
test: "這是一個屬性"
computed: {
test: { }
}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app">{{message}} --- {{avg}} --- {{test}}</div> <script src="../js/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { message: "計算平均分:", students: [ {name:"zhangsan", score:90}, {name:"lisi", score:100}, {name:"wangwu", score:99}, {name:"zhaoliu", score:89}, {name:"liuqi", score:95} ] }, computed: { avg: function() { let sum = 0; for (let i = 0; i < this.students.length; i++) { console.log(this.students[i].score); let stu = this.students[i]; sum += stu.score; } console.log("平均分:" + sum/this.students.length); return sum/this.students.length; }, test : { set: function(newValue) { this.message = newValue; console.log("調用setter") }, get: function() { return "abc" } } } }); </script> </body> </html>
看看效果
確實打印輸出了abc
computed: { avg: function() { let sum = 0; for (let i = 0; i < this.students.length; i++) { console.log(this.students[i].score); let stu = this.students[i]; sum += stu.score; } console.log("平均分:" + sum/this.students.length); return sum/this.students.length; }, avg1 : function() { return "abc" } }
雖然寫法和method差很少. 但本質上, 計算屬性仍是屬性, 因此, 和屬性的寫法是同樣的.
as