Vue 3 Composition API - watchEffect 与 watch
Posted
技术标签:
【中文标题】Vue 3 Composition API - watchEffect 与 watch【英文标题】:Vue 3 Composition API - watchEffect vs. watch 【发布时间】:2020-06-16 01:12:52 【问题描述】:所以我一直在学习 Vue Composition API,想知道 watchEffect
和 watch
之间的区别是什么。 Watch 说它和 Vue 2 手表一样,所以我猜 watchEffect 就像那个 2.0 一样?我想知道是否有任何特定情况下一个人比另一个人有很大的优势,比如停止 watchEffect 然后重新激活它而不是在普通手表中使用布尔值......或者他们只是基本上不同的方式写同样的东西。
谢谢!
参考:
观看效果:https://vue-composition-api-rfc.netlify.com/api.html#watcheffect
观看:https://vue-composition-api-rfc.netlify.com/api.html#watch
【问题讨论】:
【参考方案1】:watchEffect
似乎是简化的watch
,主要区别是
watch
可以接受一个函数或一个或多个反应属性。
在定义和反应性依赖关系发生变化时立即运行
watch
仅在响应式依赖项发生变化时运行
【讨论】:
【参考方案2】:我会使用:
watchEffect
当我想查看多个反应属性并且我不关心旧值时
watch
当我想观看一个特定的反应属性并且我可能想要旧值时
注意,以上是我使用它们的目的,但可能不是它们的唯一用途。
也可以在有关差异的文档中找到:
Compared to watchEffect, watch allows us to:
Perform the side effect lazily;
Be more specific about what state should trigger the watcher to re-run;
Access both the previous and current value of the watched state.
来源:https://composition-api.vuejs.org/api.html#watch
【讨论】:
【参考方案3】:watchEffect
是在 Vue3 中引入的,它的组合 api。据我了解,同时拥有watchEffect
和watch
的原因是为了使watch
的语义尽可能接近Vue2。 watchEffect的诞生,有兴趣的可以追溯到here和here
就目前而言,watchEffect
是一个即时/热切的手表,它使用更简洁/一致的语法(与计算一致):
watchEffect
不接受显式监视源,而是通过立即执行回调(或在源代码中调用它的效果)自动找出所有依赖项,类似于 computed
作品。因此watchEffect
必须立即运行效果。正因为如此,在设置watchEffect
时,有一个常见的陷阱(至少我必须不断提醒自己):你需要确保在你的watchEffect
的第一次执行期间,所有的依赖项确实被访问了。某些依赖项如何避免被访问?注意条件语句。
如上所述,watchEffect
将立即生效。
watchEffect
是一个深度手表。我不确定这是不是有意的。如果您在效果内使用响应式对象,则对该对象的任何更改都会导致效果重新运行,即使更改后的属性不是您访问或嵌套的属性。
如果 Vue 3 是从零开始设计的,或者不考虑保持向后兼容性,我想只有watchEffect
【讨论】:
【参考方案4】:帮助我理解 Vue 3 中 watch
和 watchEffect
之间区别的原因是将 watchEffect
视为具有副作用的 computed
。
watchEffect()
钩子的工作方式类似于computed()
钩子或computed
选项,但不是返回值,而是使用它来触发副作用。
当您想在单个反应值发生变化时触发副作用时,请使用watch
。
// Triggers whenever `user` is updated.
watch(user, () => doSomething( user: user.value, profile: profile.value ))
当您需要查看多个反应值并在其中任何更新时触发副作用时,请使用watchEffect
。
// Triggers whenever `user` *or* `profile` is updated.
watchEffect(() => doSomething( user: user.value, profile: profile.value ))
见:watch vs. watchEffect when to use what with Vue.js
【讨论】:
这没有意义。在watchEffect
上,vue.js 如何知道只触发user
和profile
的变化?您确定 watchEffect
不会在每个计算属性的每次更改时触发吗?
是的,它会在给定回调函数内的任何反应对象的每次更改时触发。 user
和 profile
是我的示例中仅有的两个响应式对象。
triggers on every change to any reactive object inside the given callback function
, 外部函数如何知道内部函数内部的引用?我不确定您是否正确理解这里发生的事情。
@JamieMarshall 这正是 Vue 中的反应式系统所做的。在高层次上,在调用watchEffect(yourMethod)
的那一刻,Vue 知道yourMethod
是一个效果并将其保存在变量中的某个位置(假设它是全局可访问的)。在yourMethod
的执行过程中,每当访问响应式引用/对象X
时,vue 都会拦截该访问(因为所有响应式对象都是代理)并记录形式为“yourMethod
依赖于X
”的依赖关系。然后,每当 X 再次更改时,yourMethod 将再次被调用。
@gagarine 在我的示例中您可以看到,回调内部使用了多个(两个)反应值。使用watchEffect
将触发对这两个反应值的更改。这可能是也可能不是你想要的。如果没有,请使用watch
。如果你在回调中只使用一个响应值,而这恰好是你想要观察的值,你可以使用watch
或watchEffect
。没错。以上是关于Vue 3 Composition API - watchEffect 与 watch的主要内容,如果未能解决你的问题,请参考以下文章
vue2升级vue3: TSX Vue 3 Composition API Refs