目录
watch
场景一:监听单个或多个特定数据的变化并执行副作用
场景二:监听多个数据源
watchEffect
场景一:自动追踪依赖并执行副作用
场景二:初始化时立即执行副作用
区别
监听方式
回调触发时机
响应式数据追踪方式
深度监听
减少watch中深度监听的性能开销的优化方法
精简被监听的数据结构
优化回调函数逻辑
精准监听
在 Vue 3 中,watch 和 watchEffect 都是用于响应式数据监听的方法,但它们的使用场景和工作方式不同。
当你需要精确地监听某个响应式数据(如 ref 或 reactive 中的某个属性)的变化,并在变化时执行一些特定的操作时,watch 非常有用。
例如,监听用户登录状态的变化,当登录状态改变时,更新页面的导航栏显示或者发起一些网络请求。
watch 也可以监听多个响应式数据的变化。例如,在一个购物车应用中,同时监听商品数量和商品价格的变化,来更新总价。
Total: {
{ totalPrice }}
watchEffect 适合于当你有一个副作用函数,它依赖于多个响应式数据,并且你希望每当这些依赖中的任何一个发生变化时,该函数自动重新执行。
例如,在一个实时数据展示应用中,有多个数据来源影响某个图表的显示,使用 watchEffect 可以方便地实现图表的自动更新。
Result: {
{ result }}
watchEffect 会在创建时立即执行一次回调函数,这在需要在组件初始化时就执行一些与响应式数据相关的操作时很有用。比如,初始化一个地图组件,其初始位置依赖于一些响应式的坐标数据。
watch
的回调函数只有在被监听的数据源发生变化时才会触发。它会传入新值和旧值两个参数,方便你对比数据变化前后的状态。watchEffect
的回调函数在组件初始化时会立即执行一次,以建立依赖关系。之后,每当依赖的响应式数据发生变化时,回调函数都会重新执行。watch
设置 deep: true
时主要针对手动指定的监听源进行深度对比。watchEffect
是基于依赖追踪,只要在回调中使用到了响应式数据,无论层次多深,Vue 都会处理其变化通知。watch中深度监听:
深度监听会消耗更多的性能,因为 Vue 需要递归地遍历对象的所有属性来检测变化。所以,建议只有在确实需要深度监听时才使用这种方式。
性能消耗原因:
减少嵌套层级:尽量简化需要深度监听的对象结构,减少不必要的嵌套层级。例如,如果你的数据结构中有一些深层嵌套且很少变化的部分,可以考虑将其提取出来,不放在深度监听的对象范围内。
按需拆分对象:对于大型复杂对象,可以根据变化频率和业务逻辑,将其拆分成多个较小的对象。只对那些需要深度监听且变化频繁的部分进行深度监听,其他部分单独处理。
避免复杂计算:确保 watch 回调函数内部不进行复杂的计算操作。如果有复杂计算需求,可以将计算逻辑提取到独立的函数中,并在需要时调用,而不是每次回调都执行。
防抖和节流
如果 watch
回调函数中执行的操作(如网络请求、DOM 操作)不希望被频繁触发,可以使用防抖或节流技术。可以使用 lodash
库中的 debounce
方法、 throttle
方法
import { debounce } from 'lodash';
watch(
() => data.nested,
debounce((newValue, oldValue) => {
// 这里执行网络请求或其他不希望频繁触发的操作
console.log('Nested value changed (debounced):', newValue, oldValue);
}, 300),
{
deep: true
}
);
import { throttle } from 'lodash';
watch(
() => data.nested,
throttle((newValue, oldValue) => {
// 这里执行网络请求或其他不希望频繁触发的操作
console.log('Nested value changed (throttled):', newValue, oldValue);
}, 300),
{
deep: true
}
);
只监听关键属性,不要对整个对象进行深度监听,而是通过计算属性或方法,只监听对象中真正需要关注的关键属性。
若碰到其他的问题 可以私信我 一起探讨学习
如果对你有所帮助还请 点赞
收藏 谢谢~!
关注收藏博客 持续更新中