在 Vue 中,computed和 watch都是用于响应数据变化的,但它们的用途、设计初衷和使用场景有显著区别。
1. computed(计算属性)
定义:
computed用于声明一个依赖于其他数据的“计算值”,它会根据依赖的数据自动计算并缓存结果,只有当依赖变化时才会重新计算。
特点:
- 缓存:依赖不变时,多次访问直接返回缓存值,不重复计算。
- 同步:通常用于同步计算,返回一个值。
- 声明式:更像一个“属性”,在模板中像普通数据一样使用。
适用场景:
需要根据现有数据计算出一个新的值,且计算逻辑较复杂或需要复用。
示例:
export default {
data() {
return { price: 100, count: 2 }
},
computed: {
total() { // 依赖 price 和 count
return this.price * this.count
}
}
}
模板中使用:{{ total }}
2. watch(侦听器)
定义:
watch用于监听某个数据的变化,并在变化时执行特定的副作用(如异步请求、复杂逻辑)。
特点:
- 无缓存:每次变化都会执行函数。
- 副作用:适合执行异步操作或复杂逻辑。
- 命令式:更像一个“事件监听”,在数据变化时做某事。
适用场景:
需要在数据变化时执行异步操作或复杂逻辑(如搜索请求、数据保存)。
示例:
export default {
data() {
return { keyword: '' }
},
watch: {
keyword(newVal, oldVal) {
this.fetchSearchResults(newVal) // 异步请求
}
}
}
3. 核心区别
| 特性 | computed | watch |
|---|---|---|
| 目的 | 计算一个新值(依赖其他数据) | 监听数据变化并执行副作用 |
| 缓存 | ✅ 有缓存,依赖不变不重新计算 | ❌ 每次变化都执行 |
| 返回值 | 必须返回一个值 | 无需返回值(执行操作即可) |
| 异步 | ❌ 不适合异步(除非配合异步组件) | ✅ 适合异步操作 |
| 语法 | 简洁,类似属性 | 需指定监听的数据和回调函数 |
| 初始化 | 默认立即计算 | 默认不立即执行(可设 immediate: true立即执行) |
4. 如何选择?
-
用
computed当:需要基于现有数据计算一个值(如:全名 = 姓 + 名;购物车总价),且希望缓存优化性能。
-
用
watch当:需要在数据变化时执行异步操作(如:搜索请求)、复杂逻辑或副作用(如:保存到本地存储、触发动画)。
5. 注意事项
- 避免在
computed中修改数据:计算属性应纯计算,不产生副作用。 watch深度监听:使用deep: true可监听对象/数组内部变化。computed的 setter:computed可定义 setter 实现双向绑定(较少用)。
简单总结:
computed是“计算出一个值” ,适合模板中使用的派生数据。watch是“监听变化并做事” ,适合数据变化时的响应操作。