computed 函数的使用方法

1. 概述

计算属性 computed 是 Vue3 组合式 API(Composition API)中用于创建计算属性的核心函数。计算属性是一个基于响应式数据自动计算、自动缓存,并且只有依赖发生变化时才会重新计算的响应式值。它允许你基于已有的响应式数据(如 refreactive 定义的变量)派生出新的状态。

计算属性最大的特点是具有缓存机制,只有在其依赖的响应式数据发生变化时才会重新计算,因此非常适合处理复杂或耗时的逻辑。

2. 基本用法

计算属性 computed 函数接收一个 getter 函数作为参数,并返回一个不可变的响应式 ref 对象。举一个简单的例子,有一个 count 值,通过计算属性得到 count 值的 double 的功能,代码如下:

<script setup lang="ts">
import { computed, ref } from "vue";
const count = ref(1);

const double = computed(() => count.value * 2);

</script>

<template>
<div>
  {{ count }} * 2 = {{ double }}
</div>
</template>

<style scoped></style>

3. 核心特性

3.1. 缓存机制

看到上面的使用方法,很多人会觉得使用函数也能达到这样的功能,代码如下:

<script setup lang="ts">
import { ref } from "vue";
const count = ref(1);

function double(count: number) {
  console.log("计算 double")
  return count * 2;
}

</script>

<template>
  <div class="wrapper">
    <div>
      {{ count }} * 2 = {{ double }}
    </div>

    <div>
      {{ count }} * 2 = {{ double }}
    </div>
  </div>
</template>

<style scoped>
.wrapper {
  grid-column: 1 / -1;
}
</style>

这里我调用了两次函数,再看使用计算属性的写法,代码如下:

<script setup lang="ts">
import { computed, ref } from "vue";
const count = ref(1);

const double = computed(()=>{
  console.log("计算 double");
  return count.value*2;
})

</script>

<template>
  <div class="wrapper">
    <div>
      {{ count }} * 2 = {{ double }}
    </div>

    <div>
      {{ count }} * 2 = {{ double }}
    </div>
  </div>
</template>

<style scoped>
.wrapper {
  grid-column: 1 / -1;
}
</style>

计算属性 computed() 函数只被执行了一遍,说明计算属性缓存了计算结果,在计算属性中,只有当其依赖的响应式数据发生变化时,才会重新执行计算。

3.2. 懒更新(Lazy Evaluation)

计算属性 computed 采用懒更新策略:计算属性不会在依赖变化时立即重新计算,而是等到该属性被实际访问时才进行重新计算。这种设计避免了不必要的计算,尤其在组件中有大量计算属性但只有部分被使用时,可以显著提升性能。

3.3. 响应式依赖追踪

计算属性会自动追踪其 getter 函数中访问的所有响应式数据,并建立依赖关系。当任一依赖发生变化时,计算属性会标记为需要更新。

4. 可写计算属性

在 Vue3 中,计算属性(computed)默认是只读的,但你可以通过为 computed() 函数传入一个包含 getset 方法的对象来创建一个可读写的计算属性。

<script setup lang="ts">
import { computed, ref } from "vue";
const count = ref(1);

const double = computed({
  get: ()=> count.value * 2,
  set: (newValue)=> {
    count.value = newValue / 2
  }
})

function bChange() {
  // 修改值
  double.value = 10;
}
</script>

<template>
  <div class="wrapper">
    <div>
      {{ count }} * 2 = {{ double }}
    </div>

    <div>
      {{ count }} * 2 = {{ double }}
    </div>
  </div>

  <button v-on:click="bChange">change</button>
</template>

<style scoped>
.wrapper {
  grid-column: 1 / -1;
}
</style>

5. 总结

计算属性 computed 是 Vue3 中处理派生状态的核心工具,其缓存机制和懒更新策略使其在处理复杂计算时兼具性能优势和代码可维护性。