computed
和watch
都是响应式数据变化的重要机制,但它们在功能、使用场景和性能表现上有显著的区别。
主要区别
- 功能和用途
1、computed:计算属性,用于基于其他数据属性进行计算,并返回一个结果。它具有缓存机制,只有当依赖的数据发生变化时才会重新计算。
2、watch:监听器,用于监听某个数据的变化,并在变化发生时执行回调函数。它不具有缓存机制,每次数据变化都会触发回调函数。
- 性能表现
1、computed:由于其缓存机制,当依赖的数据没有变化时,不会重新计算,从而节省了不必要的性能开销。
2、watch:每次数据变化都会触发回调函数,因此性能开销相对较大。
- 异步操作
1、computed:不支持异步操作,当computed内有异步操作时无法监听数据变化。
2、watch:支持异步操作,可以在回调函数中执行异步任务。
使用场景
- computed的使用场景
1、当需要根据多个数据属性计算出一个新的数据属性时,使用computed。例如,计算总价格、过滤某些数据等。
2、当需要频繁使用某个计算结果时,使用computed可以避免重复计算,提高性能。
- watch的使用场景
1、当需要在数据变化时执行一些复杂的逻辑或异步操作时,使用watch。例如,浏览器自适应、监控路由对象、API请求等。
2、当一个数据变化影响多个数据时,使用watch可以更灵活地处理这些变化。
Computed实践案例
1、基于现有数据属性进行转换
【假设你有一个价格数据,需要显示为货币格式。你可以使用computed
来自动转换这个数据。】
computed: {formattedPrice() {return this.price.toFixed (2) + ' $';}}
这样,当price
发生变化时,formattedPrice
会自动更新。
2、缓存计算结果
【computed
属性会缓存其结果,只有当依赖的数据发生变化时才会重新计算。这可以避免不必要的计算,提高性能。】
computed: {doublePrice() {return this.price * 2;}}
3、组合多个计算属性:
【可以将多个简单的计算属性组合成一个复杂的计算属性】
computed: {total() {return this.price + this税费;},formattedTotal() {return this.total.toFixed (2) + ' $';}}
Watch的最佳实践案例
1、监听路由参数
【使用watch
来监听Vue路由参数的变化,并根据参数的变化来更新组件的状态或执行相应的操作。】
watch: {'$route.params.id ': {immediate: true,handler(id) {this.fetchData (id);}}}
2、避免页面卡顿
【合理应用watch
监听器,避免页面卡顿。例如,只在需要时触发回调。】
watch: {searchInputValue(newVal) {if (newVal) {}}
}
computed属性的缓存机制简介
computed属性的缓存机制是其核心特性之一,确保了性能优化和响应式数据管理。以下是computed属性缓存机制的工作原理:
- 惰性求值:computed属性是惰性求值的,这意味着它们只有在第一次被访问时才会计算其值。之后,只要依赖的数据没有变化,computed属性将返回之前计算的结果,而不是重新计算。
- 依赖收集:computed属性会自动收集其内部表达式所依赖的响应式数据。当这些依赖的数据发生变化时,computed属性才会重新计算其值。
- 缓存机制:computed属性的结果会被缓存。只有当其依赖的数据发生变化时,缓存才会被清除并重新计算新的值。这确保了在多次访问computed属性时,如果依赖数据未变,计算过程可以避免重复执行。
- 脏检查机制:每次依赖的数据发生变化时,computed属性会将内部的脏检查标志(dirty)置为true。当再次访问computed属性时,如果脏检查标志为true,则会触发重新计算;否则,直接返回缓存的结果。
- 响应式原理:computed属性基于Vue的响应式系统实现。当依赖的数据发生变化时,Vue会检测到变化并触发相应的更新机制,从而确保computed属性能够及时更新其值。
computed属性通过惰性求值、依赖收集、缓存机制和脏检查机制,实现了高效的响应式数据管理。
参考文献链接 原文链接