在 Vue 3 中,computed 是一种计算属性,用于基于其他数据的变化自动计算和更新值。计算属性是 Vue 提供的响应式功能之一,它们通常用于在模板中显示经过处理的值,或者在 Java辑逻辑中创建动态属性。

1. 计算属性 (computed) 简介

  • computed 属性 是根据响应式数据计算出的值。
  • 它们是 惰性求值 的:只有当依赖的响应式数据发生变化时,才会重新计算,而不是每次访问时都计算。
  • 计算属性的结果会被缓存,直到它们的依赖项发生变化时才会重新计算。

2. 使用 computed

2.1 定义计算属性

在 Vue 3 中,computed 是通过 ref 或 reactive 数据来创建计算属性。你可以在 setup 函数中使用它。

<template>
  <div>
    <p>Full Name: {{ fullName }}</p>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

// 数据定义
const firstName = ref('John');
const lastName = ref('Doe');

// 计算属性
const fullName = computed(() => {
  return `${firstName.value} ${lastName.value}`;
});
</script>

2.2 计算属性与方法的区别

  • 计算属性 (computed):当依赖的响应式数据发生变化时,计算属性会自动更新,且结果是 缓存 的,直到依赖项改变。
  • 方法 (methods):每次访问时都会重新计算,没有缓存机制。

示例: 计算属性和方法的区别

<template>
  <div>
    <!-- 计算属性 -->
    <p>Full Name (computed): {{ fullName }}</p>
    <!-- 方法 -->
    <p>Full Name (method): {{ getFullName() }}</p>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const firstName = ref('John');
const lastName = ref('Doe');

// 计算属性
const fullName = computed(() => {
  return `${firstName.value} ${lastName.value}`;
});

// 方法
const getFullName = () => {
  return `${firstName.value} ${lastName.value}`;
};
</script>

解释:

  • fullName 是一个计算属性,只有当 firstName 或 lastName 发生变化时,它才会重新计算,并且会缓存计算结果。
  • getFullName 是一个方法,每次访问时都会重新执行,不会进行缓存。

2.3 计算属性的设置器(Setter)

你还可以为计算属性定义一个 setter 方法,来控制对计算属性的赋值操作。这样可以实现双向绑定或修改计算属性的计算逻辑。

<template>
  <div>
    <input v-model="fullName" />
    <p>First Name: {{ firstName }}</p>
    <p>Last Name: {{ lastName }}</p>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const firstName = ref('John');
const lastName = ref('Doe');

// 计算属性带setter
const fullName = computed({
  get() {
    return `${firstName.value} ${lastName.value}`;
  },
  set(newName) {
    const names = newName.split(' ');
    firstName.value = names[0] || '';
    lastName.value = names[1] || '';
  }
});
</script>

解释:

  • fullName 是一个计算属性,带有 getter 和 setter
  • getter 返回 firstName 和 lastName 的拼接。
  • setter 接受一个新的值,分割该值并分别赋给 firstName 和 lastName

2.4 计算属性与模板中的使用

计算属性和普通的 Vue 数据一样,可以在模板中直接使用:

<template>
  <div>
    <p>Full Name: {{ fullName }}</p>
    <button @click="changeName">Change Name</button>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const firstName = ref('John');
const lastName = ref('Doe');

const fullName = computed(() => {
  return `${firstName.value} ${lastName.value}`;
});

const changeName = () => {
  firstName.value = 'Jane';
  lastName.value = 'Smith';
};
</script>

解释:

  • 你可以在模板中直接使用计算属性 fullName,它会自动计算并显示 firstName 和 lastName 的值。
  • 当点击按钮时,changeName 方法会修改 firstName 和 lastName,并且 fullName 会自动更新。

3. computed 与 watch 的区别

  • computed:用于基于其他响应式数据计算并返回一个值,计算是懒加载和缓存的。
  • watch:用于侦听响应式数据的变化并执行副作用(比如异步操作、DOM 操作等)。

例如,你可以用 watch 来响应数据变化,而 computed 是用来计算值的。

4. 性能优化

由于计算属性是 缓存的,只有在其依赖的响应式数据发生变化时才会重新计算,因此,它在性能方面相对较高效,尤其是在模板中频繁引用的计算项。

总结

  • computed 是用来基于响应式数据计算和返回新值的,它是 懒计算 和 缓存的
  • 它可以有一个 getter 和 setter,方便你处理复杂的计算逻辑。
  • 与方法不同,计算属性会根据其依赖的数据变化自动更新,而不需要每次调用时重新计算。

希望这些解释能帮助你更好地理解 Vue 3 中的 computed!如果你有其他问题,随时告诉我!