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

相关推荐
向上的车轮2 小时前
Actix Web 不是 Nginx:解析 Rust 应用服务器与传统 Web 服务器的本质区别
前端·nginx·rust·tomcat·appche
Liudef062 小时前
基于LLM的智能数据查询与分析系统:实现思路与完整方案
前端·javascript·人工智能·easyui
潘小安2 小时前
跟着 AI 学(三)- spec-kit +claude code 从入门到出门
前端·ai编程·claude
金梦人生3 小时前
让 CLI 更友好:在 npm 包里同时支持“命令行传参”与“交互式对话传参”
前端·npm
Mintopia3 小时前
🐋 用 Docker 驯服 Next.js —— 一场前端与底层的浪漫邂逅
前端·javascript·全栈
Mintopia3 小时前
物联网数据驱动 AIGC:Web 端设备状态预测的技术实现
前端·javascript·aigc
一个W牛3 小时前
报文比对工具(xml和sop)
xml·前端·javascript
鸡吃丸子4 小时前
浏览器是如何运作的?深入解析从输入URL到页面渲染的完整过程
前端
作业逆流成河4 小时前
🔥 enum-plus 3.0:介绍一个天花板级的前端枚举库
前端·javascript·前端框架
爱喝水的小周4 小时前
《UniApp 页面导航跳转全解笔记》
前端·uni-app