一般, 咱们是在模板中, 经过插值语法显示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