深入浅出 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 的学习者。

相关推荐
king王一帅4 小时前
Incremark Solid 版本上线:Vue/React/Svelte/Solid 四大框架,统一体验
前端·javascript·人工智能
智航GIS8 小时前
10.4 Selenium:Web 自动化测试框架
前端·python·selenium·测试工具
前端工作日常8 小时前
我学习到的A2UI概念
前端
徐同保9 小时前
为什么修改 .gitignore 后还能提交
前端
一只小bit9 小时前
Qt 常用控件详解:按钮类 / 显示类 / 输入类属性、信号与实战示例
前端·c++·qt·gui
Mr -老鬼9 小时前
前端静态路由与动态路由:全维度总结与实践指南
前端
颜酱10 小时前
前端必备动态规划的10道经典题目
前端·后端·算法
wen__xvn10 小时前
代码随想录算法训练营DAY10第五章 栈与队列part01
java·前端·算法
大怪v11 小时前
前端佬们!!AI大势已来,未来的上限取决你的独特气质!恭请批阅!!
前端·程序员·ai编程
Mr -老鬼11 小时前
功能需求对前后端技术选型的横向建议
开发语言·前端·后端·前端框架