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,想知道 watchEffectwatch 之间的区别是什么。 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。据我了解,同时拥有watchEffectwatch 的原因是为了使watch 的语义尽可能接近Vue2。 watchEffect的诞生,有兴趣的可以追溯到here和here

就目前而言,watchEffect 是一个即时/热切的手表,它使用更简洁/一致的语法(与计算一致):

    watchEffect 不接受显式监视源,而是通过立即执行回调(或在源代码中调用它的效果)自动找出所有依赖项,类似于 computed作品。因此watchEffect 必须立即运行效果。正因为如此,在设置watchEffect 时,有一个常见的陷阱(至少我必须不断提醒自己):你需要确保在你的watchEffect 的第一次执行期间,所有的依赖项确实被访问了。某些依赖项如何避免被访问?注意条件语句。 如上所述,watchEffect 将立即生效。 watchEffect 是一个深度手表。我不确定这是不是有意的。如果您在效果内使用响应式对象,则对该对象的任何更改都会导致效果重新运行,即使更改后的属性不是您访问或嵌套的属性。

如果 Vue 3 是从零开始设计的,或者不考虑保持向后兼容性,我想只有watchEffect

【讨论】:

【参考方案4】:

帮助我理解 Vue 3 中 watchwatchEffect 之间区别的原因是将 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 如何知道只触发userprofile 的变化?您确定 watchEffect 不会在每个计算属性的每次更改时触发吗? 是的,它会在给定回调函数内的任何反应对象的每次更改时触发。 userprofile 是我的示例中仅有的两个响应式对象。 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。如果你在回调中只使用一个响应值,而这恰好是你想要观察的值,你可以使用watchwatchEffect。没错。

以上是关于Vue 3 Composition API - watchEffect 与 watch的主要内容,如果未能解决你的问题,请参考以下文章

vue2升级vue3: TSX Vue 3 Composition API Refs

Vue 3 Composition API实战前瞻

Vue 3 Composition API 实战前瞻

为啥在 Vue 3 的 Composition API 中使用“API”这个词?

Vue3新特性——Composition API详解

Vue 3 Composition API - watchEffect 与 watch