🧠计算属性
在 Vue 开发中,计算属性(computed
)是一个非常核心的概念。它不仅可以简化模板逻辑,还能自动追踪依赖并缓存结果,提高性能。
🎯 一、为什么需要计算属性?
当你需要根据响应式状态进行复杂的逻辑运算时,如果直接写在模板里,会导致代码臃肿、难以维护。
✅ 使用计算属性的目的:
- 将复杂逻辑封装到一个变量中
- 自动追踪响应式依赖,仅在必要时重新计算
- 提升性能,避免重复执行相同计算
- 减少模板中的冗余代码
🛠️ 基本用法:使用 computed
函数
import {computed, ref} from 'vue'
const count = ref(1)
const doubleCount = computed(() => {
return count * 2
})
🔍 参数与返回值说明:
内容 | 描述 |
---|---|
入参 | 接受一个 getter 函数 |
返回值 | 返回一个只读的 ref 对象 |
访问方式 | 通过 .value 获取计算结果 |
⚙️ 特性解析:
- 自动追踪依赖:Vue 会监听
count.value
的变化,并在变更时重新计算。 - 缓存机制:只要
count
没有改变,多次访问doubleCount.value
都会返回缓存的结果,不会重复执行函数
⚠️ 注意事项:这些坑你别踩!
// ❌如果没有响应式依赖,则计算属性永远不会更新
const now = computed(() => Date.now())
// 💡如果你需要动态时间戳,请手动触发更新或使用 `watchEffect` 等响应式副作用函数
// 如果不需要缓存,直接在模板中调用方法,结果也是一样的
✨二、可以修改的计算属性- 使用getter和setter创建
可以反过来通过计算属性更新相关依赖 => 有时候我们不仅想“读取”计算属性,还想“设置”它来反向更新源数据。
示例代码:
const firstName = ref('f')
const secontName = ref('c')
// getter => 拼接成完整的姓名
// setter => 允许通过赋值的方式更新fristName 和 secontName
computed({
get(){
return firstName.value + '' + secondName.value
},
set(newVal){
[firstName.value, secondName.value] = newVal.split(' ')
},
})
🔄 三、如何获取上一次的计算结果?(Vue 3.4+ 新特性)
你可以通过 getter
函数的第一个参数,拿到上一次的计算结果。
const myComputed = computed((prev) => {
// prev 是上一次的返回值
if (someCondition) {
return prev
}
return someNewValue
})
📌 应用场景:
- 需要根据历史状态做判断
- 控制某些状态的变更逻辑(如防抖、节流等)
🧪 四、实践中的注意事项(避坑指南)
1. Getter 不应有副作用
Getter 的职责是:计算并返回一个值,不要做以下事情:
❌ 不推荐行为:
- 修改其他响应式状态
- 发起异步请求(如
fetch
) - 直接操作 DOM
✅ 正确做法:
- 使用
watch
或watchEffect
来处理副作用
2. 不要直接修改计算属性的值
// ❌ 错误写法 fullName.value = 'Alice Johnson'
- 计算属性本质上是一个“快照”,它是基于源状态生成的。
- 修改它不会影响原始数据,也没有意义。
- 如果你需要通过赋值来改变状态,请使用可写的
computed(setter)
。
🎁 五、总结:computed 的黄金法则
场景 | 推荐做法 |
---|---|
复杂逻辑展示 | 使用 computed 简化模板 |
缓存计算结果 | 利用其缓存机制提升性能 |
支持双向绑定 | 使用 getter + setter |
获取上次结果 | Vue 3.4+ 中使用 (prev) => {} |
有副作用操作 | 使用 watch 替代 |
💬 六、结语
computed
是 Vue 响应式系统中最强大、最常用的工具之一。理解它的原理和使用方式,能让你写出更优雅、更高效的 Vue 应用。