阿杰,我来帮你整理一份 Vue 3 computed 全解析 + 示例,包含原理、用法、注意事项和对比。


1. computed 是什么?

  • 作用:根据响应式数据计算出一个“衍生值”,类似 计算属性
  • 特点
    1. 缓存:只有依赖的数据发生变化时才会重新计算。
    2. 响应式:返回值可以直接在模板中使用,并会随依赖自动更新。
    3. 可读可写:支持只读和可写两种形式。

2. 基本用法(只读)

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

const count = ref(0)

// 计算属性
const double = computed(() => count.value * 2)
</script>

<template>
  <div>
    <p>count: {{ count }}</p>
    <p>double: {{ double }}</p>
    <button @click="count++">+1</button>
  </div>
</template>

说明

  • double 会缓存计算结果,只有当 count 发生变化时才重新计算。
  • computed 内部依赖响应式数据(如 refreactive)才能触发更新。

3. 可写的 computed

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

const firstName = ref('阿')
const lastName = ref('杰')

// 可写计算属性
const fullName = computed({
  get: () => `${firstName.value} ${lastName.value}`,
  set: (val) => {
    const names = val.split(' ')
    firstName.value = names[0]
    lastName.value = names[1]
  }
})
</script>

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

说明

  • get:获取计算属性值
  • set:设置计算属性时触发

4. computed vs watch

特性computedwatch
返回值有返回值,可直接绑定模板无返回值,只做副作用
缓存有缓存,只在依赖变化时重新计算没缓存,每次依赖变化都会触发
用途计算衍生数据监听变化做异步或副作用

示例:

// watch
watch(count, (newVal, oldVal) => {
  console.log(`count changed from ${oldVal} to ${newVal}`)
})


5. 对 reactive 对象使用 computed

const state = reactive({ count: 1, price: 100 })

const total = computed(() => state.count * state.price)

说明

  • computed 会自动收集依赖(state.countstate.price),依赖变化时自动更新。

6. 小技巧

  1. 在模板中直接使用
<p>Total: {{ total }}</p>

  1. 组合多个 computed
const discount = ref(0.8)
const finalPrice = computed(() => total.value * discount.value)

  1. 避免在 computed 内做副作用
// ❌ 不推荐
const double = computed(() => {
  console.log('计算') // 每次访问都会打印
  return count.value * 2
})

  • 副作用应使用 watchwatchEffect