Skip to content

基础

基本使用

computed: https://cn.vuejs.org/guide/essentials/computed.html

vue
<script setup>
  // 1. 引入
  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  ComputedRef
  // 2. 使用
  const publishedBooksMessage = computed(() => {
    // 3. 注意 return
    return author.books.length > 0 ? 'Yes' : 'No'
  })
</script>

<template>
  <p>Has published books:</p>
  <span>{{ publishedBooksMessage }}</span>
</template>

计算属性 ref ,可以通过publishedBooksMessage.value访问, 计算属性在模板中也会自动解包,因此在模板表达式中引用时无需添加 .value

类型标注

computed() 会自动从其计算函数的返回值上推导出类型:

typescript
import { ref, computed } from 'vue'

const count = ref(0)

// 推导得到的类型:ComputedRef<number>
const double = computed(() => count.value * 2)

// => TS Error: Property 'split' does not exist on type 'number'
const result = double.value.split('')

泛型显示指定类型

typescript
const double = computed<number>(() => {
  // 若返回值不是 number 类型则会报错
  return ...
})

计算属性缓存

方法

方法调用总是会在重渲染发生时再次执行函数

vue
<!-- 如果定义为方法,每次渲染都会调用函数 -->
<p>{{ calculateBooksMessage() }}</p>

// 组件中
function calculateBooksMessage() {
  return author.books.length > 0 ? 'Yes' : 'No'
}

计算属性

计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。

只要 author.books 不改变,无论多少次访问 publishedBooksMessage 都会立即返回先前的计算结果,而不用重复执行 getter 函数。

typescript
const publishedBooksMessage = computed(() => {
  // 3. 注意 return
  return author.books.length > 0 ? 'Yes' : 'No'
})

computed-setter

计算属性默认是只读的。当尝试修改一个计算属性时,warning~~~~, 下面是可写计算属性的声明方式

typescript
<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>

当运行 fullName.value = 'John Doe' 时,setter 会被调用而 firstName 和 lastName 会随之更新

最佳实践

Getter不应有副作用

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

避免直接修改计算属性值

计算属性的返回值应该被视为只读的,并且永远不应该被更改——应该更新它所依赖的源状态以触发新的计算

computed特点

  1. 计算属性值会基于其响应式依赖被缓存
  2. 计算属性默认是只读的,避免修改其值(forever)