【Vue.js】Composition API - computed()

200 阅读2分钟

概述:

在 composition API 中,computed 是一个用于模板计算优化渲染的高阶函数。

import { reactive, computed } from 'vue';

const state = reactive({
  num1: 1,
  num2: 2,
  num3: 3,
});

const totalNum = computed(() => {
  return state.num1 + state.num2 + state.num3;
});

为什么要使用计算属性?

模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。(Vue 认为,模板中不应该有太多的逻辑交互)

用法:

在 composition API 中:

  1. computed 接受一个 getter 函数,返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。
<script setup>
  import { reactive, computed } from 'vue';

  const author = reactive({
    name: 'John Doe',
    books: [
      'Vue 2 - Advanced Guide',
      'Vue 3 - Basic Guide',
      'Vue 4 - The Mystery'
    ]
  });

  // 一个计算属性 ref
  const publishedBooksMessage = computed(() => {
    return author.books.length > 0 ? 'Yes' : 'No'
  });
</script>

<template>
  <p>Has published books:</p>
  <span>{{ publishedBooksMessage }}</span>
</template>
  1. computed 也可以接受一个带有 getset 函数的对象来创建一个可写的 ref 对象。
<script setup>
  import { ref, computed } from 'vue';
  
  const firstName = ref('John');
  const lastName = ref('Doe');
  
  const fullName = computed({
    // getter
    get() {
      return firstName.value + ' ' + lastName.value
    },
    // setter
    set(newValue) {
      // 注意:我们这里使用的是解构赋值语法
      [firstName.value, lastName.value] = newValue.split(' ')
    }
  });
</script>
  1. 可以使用 computed 的第二个参数进行调试 ({ onTracked, onTriggered })
<script setup>
  import { computed } from 'vue';
  
  const plusOne = computed(() => count.value + 1, {
  onTrack(e) {
    debugger
  },
  onTrigger(e) {
    debugger
  }
});
</script>

computed 的用途:

  1. 创建一个只读的计算属性 computedRef
  2. 创建一个可读可写的计算属性 computedRef
  3. 记忆并缓存视图中需要的复杂的运算逻辑

使用 computed 时的一些注意点:

Getter 不应有副作用

计算属性的 getter 应只做计算而没有任何其他的副作用,这一点非常重要,请务必牢记。举例来说,不要在 getter 中做异步请求或者更改 DOM!一个计算属性的声明中描述的是如何根据其他值派生一个值。因此 getter 的职责应该仅为计算和返回该值。在之后的指引中我们会讨论如何使用侦听器根据其他响应式状态的变更来创建副作用。

避免直接修改计算属性值

从计算属性返回的值是派生状态。可以把它看作是一个“临时快照”,每当源状态发生变化时,就会创建一个新的快照。更改快照是没有意义的,因此计算属性的返回值应该被视为只读的,并且永远不应该被更改——应该更新它所依赖的源状态以触发新的计算。