Vue入门到精通:核心语法—计算属性

在这里插入图片描述

Vue入门到精通:核心语法—计算属性

计算属性是Vue.js中一个非常强大的功能,它允许我们根据现有的数据动态地计算出新的值。计算属性在模板中使用时,就像普通的属性一样,但它们是基于依赖进行缓存的,只有当相关依赖发生改变时才会重新计算。这使得计算属性在处理复杂逻辑时非常有用,同时还能提高应用的性能。

1.计算属性的基本用法

计算属性是通过computed选项来定义的,它是一个对象,其中每个键值对都代表一个计算属性。计算属性的值是一个函数,这个函数会返回计算后的结果。

const app = Vue.createApp({
    
    
  data() {
    
    
    return {
    
    
      firstName: 'John',
      lastName: 'Doe'
    };
  },
  computed: {
    
    
    fullName() {
    
    
      return this.firstName + ' ' + this.lastName;
    }
  }
});

在上面的例子中,我们定义了一个计算属性fullName,它依赖于firstNamelastName这两个数据属性。每当firstNamelastName发生变化时,fullName会自动重新计算并更新。

2.计算属性的特点

(1) 缓存:计算属性是基于它们的依赖进行缓存的。只有当相关依赖发生改变时,计算属性才会重新计算。这意味着如果依赖没有变化,多次访问计算属性不会触发重新计算,从而提高性能。

(2)响应式:计算属性是响应式的,当依赖的数据发生变化时,计算属性会自动更新。

(3)只读:默认情况下,计算属性是只读的。如果你需要让计算属性可写,可以提供一个setter函数。

computed: {
    
    
  fullName: {
    
    
    get() {
    
    
      return this.firstName + ' ' + this.lastName;
    },
    set(newValue) {
    
    
      const names = newValue.split(' ');
      this.firstName = names[0];
      this.lastName = names[names.length - 1];
    }
  }
}

在这个例子中,我们为fullName提供了一个getter和一个setter。这样,我们就可以通过修改fullName来同时更新firstNamelastName

3.使用场景

计算属性非常适合用于以下场景:

  • 复杂的逻辑:当需要在模板中展示基于多个数据属性的复杂计算结果时,可以使用计算属性。
  • 性能优化:当某些计算结果在多次渲染中重复使用时,计算属性可以避免不必要的重复计算,提高性能。
  • 数据转换:当需要将数据从一种格式转换为另一种格式时,可以使用计算属性进行处理。

4.计算属性和method方法

通过在模板中调用method方法可以实现与计算属性相同的效果。

无论是在初始化显示还是后续更新显示时,计算属性和method方法的效果都是相同的。尽管如此,在实际开发中,我们通常选择使用计算属性来实现这一功能。这是因为计算属性具有缓存机制,能够将计算属性函数返回的结果数据进行缓存处理。如果结果数据需要在页面中多次显示,那么计算属性函数只会执行一次,而method方法则会对应执行多次。这样对比下来,计算属性的效率明显高于method方法。

5.计算属性的setter

计算属性在默认情况下仅能通过计算属性函数得出结果。当开发者尝试修改一个计算属性时,会收到一个运行时警告提示。

在这里插入图片描述

现有3个需求,具体如下。

①姓名由“姓-名”组成,姓名的初始显示为“A-B”。

②当改变姓或名时,姓名能自动同步变化。

③姓和名能实时与姓名同步。

下面对数据进行分析和设计。可以将“姓”和“名”设计为两个独立的data数据属性。通过使用v-model指令,我们可以实现这两个数据属性与输入框之间的双向数据绑定。然而,由于“姓名”是由“姓”和“名”动态组合而成的,因此我们可以将“姓名”设计为一个计算属性。这样,当“姓”或“名”发生变化时,“姓名”会自动更新,并且我们仍然可以使用v-model将“姓名”绑定到input标签上。具体的实现代码如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>姓名生成器</title>
    <!-- 引入Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <span>姓: <input type="text" v-model="firstName"></span>
        <span>名: <input type="text" v-model="lastName"></span>
        <span>姓名: <input type="text" placeholder="格式: 姓-名" v-model="fullName" /></span>
    </div>

    <script>
        new Vue({
      
      
            el: '#app',
            data: {
      
      
                firstName: 'A',
                lastName: 'B'
            },
            computed: {
      
      
                fullName() {
      
      
                    return this.firstName + this.lastName;
                }
            }
        });
    </script>
</body>
</html>

在上面的代码中,我们在data对象中定义了firstName和lastName两个计算属性,在computed配置中定义了计算属性fullName,并通过v-model将其绑定到对应的input标签上。

运行之后初始页面:

在这里插入图片描述

改变姓或名时,姓名能自动同步变化

在这里插入图片描述

计算属性fullName在Vue中默认是只读的,它只能根据其他数据属性计算并返回一个值。如果需要设置计算属性的值,可以通过定义计算属性的getter和setter来实现。下面是修改后的代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>姓名生成器</title>
    <!-- 引入Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <span>姓: <input type="text" v-model="firstName"></span>
        <span>名: <input type="text" v-model="lastName"></span>
        <span>姓名: <input type="text" placeholder="格式: 姓-名" v-model="fullName" /></span>
    </div>

    <script>
        new Vue({
      
      
            el: '#app',
            data: {
      
      
                firstName: 'A',
                lastName: 'B'
            },
            computed: {
      
      
              fullName: {
      
      
                // getter
                get () {
      
      
                  console.log('fullName, get()')
                  return this.firstName + '-' + this.lastName;
                },
                // setter
                set(value) {
      
      
                  log('fullName set()', value)
                  const names=value.split('-')
                  this.firstName =names[0]
                  this.lastName = names[names.length - 1]
                }
              }
            }
        });
    </script>
</body>
</html>

在这个修改后的例子中,我们为计算属性fullName提供了一个对象,其中包含getset两个函数。get函数用于返回计算后的完整姓名,而set函数则允许我们通过输入新的完整姓名来更新firstNamelastName。这样,用户就可以直接在“姓名”输入框中输入或修改完整的姓名,而Vue会自动解析并更新姓和名。

在这里插入图片描述