Vue 计算属性(2)

102 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

1. computed vs methods

上一篇文章,我们会发现计算属性(computed) 和 methods 的实现看起来差别不大。那么计算属性和 methods 究竟有什么差异呢?我们需要知道计算属性是有缓存的。来看同一个计算多次使用的情形:

<body> 元素中的代码:

<div id="app"></div>

<template id="my-app">
  <!-- 1. 使用 methods -->
  <h2>{{ getFullName() }}</h2>
  <h2>{{ getFullName() }}</h2>
  <h2>{{ getFullName() }}</h2>

  <!-- 2. 使用 computed -->
  <h2>{{ fullName }}</h2>
  <h2>{{ fullName }}</h2>
  <h2>{{ fullName }}</h2>
</template>

<script src="./js/vue.js"></script>
<script>
  const App = {
    data() {
      return {
        firstName: 'Shane',
        lastName: 'Filan',
      }
    },
    computed: {
      fullName() {
        console.log('computed 中的 fullName 中的计算(计算属性 fullName 的 getter 被调用了)');
        return this.firstName + ' ' + this.lastName;
      }
    },
    methods: {
      getFullName() {
        console.log('methods 中的 getFullName 中的计算(methods 中的 getFullName 方法被调用了)');
        return this.firstName + ' ' + this.lastName;
      }
    },
    template: '#my-app'
  };

  Vue.createApp(App).mount('#app');
</script>

运行结果:

image-20210821214924641.png

可以看到,因为方法被调用了 3 次,所以方法中的打印语句输出了 3 次,而计算属性同样被调用了 3 次,但计算属性中的打印语句却只输出了 1 次。所以说,计算属性是有缓存的,当我们多次使用计算属性时,计算属性中的运算只会执行一次。

计算属性还会随着依赖的数据(比如上面的 firstName)的改变,自动重新计算,并把最新的值缓存下来,后面再使用时就不需要再进行计算,而是直接使用缓存的最新的值了:

我们在模板中添加一个按钮,在 methods 中添加 changeFirstName() 方法并绑定按钮的 click 事件:

<template id="my-app">
  <button @click="changeFirstName">修改 firstName</button>
  <!-- 1. 使用 methods -->
  <h2>{{ getFullName() }}</h2>
  <h2>{{ getFullName() }}</h2>
  <h2>{{ getFullName() }}</h2>

  <!-- 2. 使用 computed -->
  <h2>{{ fullName }}</h2>
  <h2>{{ fullName }}</h2>
  <h2>{{ fullName }}</h2>
</template>
methods: {
  getFullName() {
    console.log('methods 中的 getFullName 中的计算(methods 中的 getFullName 方法被调用了)');
    return this.firstName + ' ' + this.lastName;
  },
  changeFirstName() {
    this.firstName = 'Coder';
  }
}

页面效果:

computed vs methods.gif

可以看到,当我们修改了 data 中的 firstName 之后,由于 data 中的数据是响应式的,所以页面上所有用到了 firstName 的地方都会进行更新,页面会重新渲染(这涉及到响应式原理,我们后面会讲)。并且,通过控制台打印的内容,我们也可以发现方法再次被调用了 3 次,而计算属性依旧只被调用了 1 次。

那计算属性到底是怎么缓存起来的呢?而且它缓存起来之后,是怎么根据依赖的 data 的改变,再把缓存的值改掉呢?这些问题都和响应式原理有关,我们后面再讲(计算属性是如何依赖响应式系统中的数据,当这些数据改变时,计算属性是如何重新进行计算的,即计算属性的实现原理)。

小结:

  • 计算属性会基于其依赖关系进行缓存
  • 如果依赖的数据不发生变化,计算属性不会重新进行计算
  • 如果依赖的数据发生变化,在使用时,计算属性会重新进行计算