1. 什么是计算属性?

我们知道,在模板中可以直接用插值语法显示一些data中的数据。
但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示

  • 比如我们有 firstName 和 lastName 两个变量,我们需要显示完整的名称。
  • 但是如果多个地方都需要显示完整的名称,我们就需要写多个 {{firstName}} {{lastName}}

我们可以将上面的代码转换成计算属性:

  • 我们发现计算属性是写在实例的 computed选项中的。

image.png

  1. <div id="app">
  2. <h2>{{firstName + ' ' + lastName}}</h2>
  3. <h2>{{firstName}} {{lastName}}</h2>
  4. <h2>{{getFullName()}}</h2>
  5. <h2>{{fullName}}</h2>
  6. </div>
  7. <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
  8. <script type="text/javascript">
  9. const app = new Vue({
  10. el: '#app',
  11. data: {
  12. firstName: 'LeBron',
  13. lastName: 'James',
  14. },
  15. // computed: 计算属性
  16. computed: {
  17. fullName: function () {
  18. return this.firstName + ' ' + this.lastName
  19. }
  20. },
  21. methods: {
  22. getFullName: function () {
  23. return this.firstName + ' ' + this.lastName
  24. }
  25. }
  26. })
  27. </script>

2. 计算属性的复杂操作

image.png

  1. <div id="app">
  2. <h2>总价格: {{totalPrice}}</h2>
  3. </div>
  4. <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
  5. <script type="text/javascript">
  6. const app = new Vue({
  7. el: '#app',
  8. data: {
  9. books: [
  10. {id: 110, name: 'Unix编程艺术', price: 119},
  11. {id: 111, name: '代码大全', price: 105},
  12. {id: 112, name: '深入理解计算机原理', price: 98},
  13. {id: 113, name: '现代操作系统', price: 87}
  14. ]
  15. },
  16. computed: {
  17. totalPrice: function () {
  18. // return this.books.reduce()
  19. let result = 0
  20. //1
  21. /* for (let i = 0; i < this.books.length; i ++ ) {
  22. result += this.books[i].price
  23. } */
  24. //2
  25. /* for (let i in this.books) {
  26. result += this.books[i].price
  27. } */
  28. //3
  29. for (let book of this.books) {
  30. result += book.price
  31. }
  32. return result
  33. }
  34. }
  35. })
  36. </script>

3. 计算属性的setter和getter

每个计算属性都包含一个 getter 和一个 setter

  • 在上面的例子中,我们只是使用 getter 来读取
  • 在某些情况下,你也可以提供一个 setter 方法(不常用)
  • 在需要写 setter 的时候,代码如下:

image.png

  1. <div id="app">
  2. <h2>{{fullName}}</h2>
  3. </div>
  4. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" type="text/javascript" charset="utf-8"></script>
  5. <script type="text/javascript">
  6. const app = new Vue({
  7. el: '#app',
  8. data: {
  9. firstName: 'Kobe',
  10. lastName: 'Bryant'
  11. },
  12. //计算属性一般没有set方法,只读属性
  13. computed: {
  14. fullName: {
  15. set: function (newValue) {
  16. const name = newValue.split(' ')
  17. this.firstName = name[0]
  18. this.lastName = name[1]
  19. },
  20. get: function () {
  21. return this.firstName + ' ' + this.lastName
  22. }
  23. }
  24. }
  25. })
  26. </script>

如果没有写 setter方法,那么 fullName 为一个只读属性:
image.png

4. 计算属性的缓存

我们可能会考虑这个一个问题:

  • methods 和 computed 看起来都可以实现我们的功能,
  • 那么为什么还要多一个计算属性这个东西呢?
  • 原因:计算属性会进行缓存,如果多次使用时,计算属性只会调用一次

image.png

  1. <div id="app">
  2. <!-- 1. 直接拼接:语法过于繁琐-->
  3. <h2>{{firstName}} {{lastName}}</h2>
  4. <!-- 2. 通过定义methods -->
  5. <h2>{{getFullName()}}</h2>
  6. <h2>{{getFullName()}}</h2>
  7. <h2>{{getFullName()}}</h2>
  8. <!-- 3. 通过computed -->
  9. <h2>{{fullName}}</h2>
  10. <h2>{{fullName}}</h2>
  11. <h2>{{fullName}}</h2>
  12. </div>
  13. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" type="text/javascript" charset="utf-8"></script>
  14. <script type="text/javascript">
  15. const app = new Vue({
  16. el: '#app',
  17. data: {
  18. firstName: 'Kobe',
  19. lastName: 'Bryant'
  20. },
  21. computed: {
  22. fullName: function () {
  23. console.log("fullName");
  24. return this.firstName + ' ' + this.lastName
  25. }
  26. },
  27. methods: {
  28. getFullName: function () {
  29. console.log("getFullName()");
  30. return this.firstName + ' ' + this.lastName
  31. }
  32. }
  33. })
  34. </script>