深入浅出 Vue 的 computed:不仅仅是“计算属性”那么简单!

在 Vue 的世界里,响应式是它的灵魂。而 computed(计算属性)正是这个响应系统中一颗闪耀的明星。它不仅能提升代码的可读性和性能,还能优雅地处理复杂逻辑。本篇文章将带你系统掌握 computed 的用法与底层原理,彻底理解它与 watch、methods 的区别与适用场景。


一、什么是 computed?

在 Vue 中,computed 是基于响应式依赖进行缓存的计算属性

你可以把它想象成模板里的"智能变量"------只要依赖的数据没变,它就不会重新计算,性能非常好。

✅ 官方定义:

计算属性是基于它们的响应式依赖进行缓存的,只有在相关依赖发生变化时它们才会重新求值。


二、为什么不用 methods 或 watch 替代 computed?

对比项 computed methods watch
是否有缓存 ✅ 有缓存,依赖不变不重新计算 ❌ 每次调用都重新计算 ❌ 不涉及计算返回值
适用场景 表达式逻辑较重、需要缓存结果 简单计算或不频繁调用 监听值变化并触发副作用
调用方式 模板中当变量使用 模板中当函数调用 只能在 JS 中使用

三、computed 的基本用法

js 复制代码
<template>
  <div>
    <p>姓名:{{ fullName }}</p>
    <input v-model="firstName" placeholder="姓">
    <input v-model="lastName" placeholder="名">
  </div>
</template>

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

const firstName = ref('张')
const lastName = ref('三')

// computed 会根据依赖的 firstName 和 lastName 自动更新
const fullName = computed(() => `${firstName.value} ${lastName.value}`)
</script>

✅ 说明:

  • 只要 firstName 或 lastName 任意一个变化,fullName 就会自动重新计算。
  • 若两者都没变,fullName 不会重复计算,性能更优。

四、使用 getter 和 setter 实现双向绑定

有时候我们希望通过 computed 实现读写双向能力,比如:

js 复制代码
<script setup>
import { ref, computed } from 'vue'

const firstName = ref('李')
const lastName = ref('雷')

const fullName = computed({
  get: () => `${firstName.value} ${lastName.value}`,
  set: (val) => {
    const parts = val.split(' ')
    firstName.value = parts[0] || ''
    lastName.value = parts[1] || ''
  }
})
</script>

<template>
  <input v-model="fullName" />
</template>

✅ 说明:

  • 用户修改 fullName 时,会通过 set 方法反向拆分出 firstName 和 lastName。
  • 这在表单处理和数据映射中非常实用。

五、和 watch 的典型区别场景

js 复制代码
<script setup>
import { ref, computed, watch } from 'vue'

const price = ref(100)
const quantity = ref(2)

// 计算总价
const total = computed(() => price.value * quantity.value)

// watch 监听价格变化,并打印日志(副作用)
watch(price, (newVal, oldVal) => {
  console.log(`价格从 ${oldVal} 变为 ${newVal}`)
})
</script>

✅ 区别说明:

  • computed 用来返回一个值(总价)。
  • watch 是为了"做点事情"(比如打印日志、发请求)------这就是"副作用"。

六、多个 computed 嵌套组合使用

有时候我们会有多个计算属性依赖彼此:

js 复制代码
<script setup>
import { ref, computed } from 'vue'

const salary = ref(8000)

const tax = computed(() => salary.value * 0.1)
const incomeAfterTax = computed(() => salary.value - tax.value)
</script>

<template>
  <p>工资:{{ salary }}</p>
  <p>税:{{ tax }}</p>
  <p>税后收入:{{ incomeAfterTax }}</p>
</template>

Vue 会自动追踪依赖关系,无需担心顺序或重复计算的问题。


七、computed 的调试技巧

有时候你可能发现 computed 没有更新?建议你检查:

  1. 依赖的响应式数据是否写错?
  2. 是否使用了 .value?
  3. 是否用了 reactive 而你直接解构了对象?
js 复制代码
// 错误示范
const person = reactive({ age: 30 })
const age = computed(() => person.age) // 如果你解构了 person.age,computed 就无法感知变化

解决方式:要么别解构,要么使用 toRef 保持响应性。


八、总结:什么时候使用 computed?

使用时机 推荐方式
需要显示一个依赖多个值计算的变量 用 computed
需要在变量变化时执行异步操作、副作用 用 watch
模板中临时调用简单函数,无需缓存 用 methods

九、写在最后

computed 不仅仅是"计算属性",它代表的是 Vue 响应系统中智能、高效的表达方式

使用得当,可以让你的模板更简洁、逻辑更清晰、性能更优秀。

希望这篇文章能帮你真正掌握 computed,而不是只是"知道怎么用"。如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、分享给更多 Vue 的学习者。

相关推荐
郭老二8 小时前
【前端】vue3:编译步骤
前端
不在逃避q9 小时前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁9 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
The Chosen One9859 小时前
高进度算法模板速记(待完善)
java·前端·算法
陈随易9 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
新中地GIS开发老师11 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
用户0595401744611 小时前
大模型对话记忆持久化踩坑实录:用 Playwright 自动化测了 300 次,终于揪出会话丢失的真凶
前端·css
丙氨酸長鏈11 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen12 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒12 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端