遇到了一个关于 Vue 响应式的问题

2022-06-16 16:04:07 +08:00
 Curtion

前俩天在看 Vue3 的代码的时候看到了eddect.ts中一段奇怪的代码,我寻思着这不是在脱裤子放屁吗?

export function triggerEffects(
  dep: Dep | ReactiveEffect[],
  debuggerEventExtraInfo?: DebuggerEventExtraInfo
) {
  // spread into array for stabilization
  const effects = isArray(dep) ? dep : [...dep]
  for (const effect of effects) {
    if (effect.computed) {
      triggerEffect(effect, debuggerEventExtraInfo)
    }
  }
  for (const effect of effects) {
    if (!effect.computed) {
      triggerEffect(effect, debuggerEventExtraInfo)
    }
  }
}

经过搜索发现在这么写是有原因的: https://github.com/vuejs/core/issues/5720

这个 issues 展示的列子显示computed没有在正确的时机计算结果。

后续 Vue 官方修复了这个问题。

但是我还有一个问题: SFC 链接

如果使用 3.2.33(#5720 修复前的版本)执行上述 SFC ,得到的结果是

computed count: 0
before inc plusOne: 1
watch count: 1
watch plusOne: 1
computed count: 1
after inc plusOne: 2

可以看到watch plusOne的值是错误的,当然这个问题已经解决了。

如果使用最新的版本,那么顺序是

computed count: 0
before inc plusOne: 1
computed count: 1
after inc plusOne: 2
watch count: 1
watch plusOne: 2

看起来结果正确了,但是watch的位置却在after inc plusOne之后了?

这是预测的行为吗? 个人觉得这引入了一个新的问题。。但是由于我的水平有限,无法理清内部原理,所以无法确定这是不是正常的。

这个可能和 Vue 的scheduler有关?

904 次点击
所在节点    问与答
2 条回复
free9fw
2022-06-16 16:53:58 +08:00
make sure computed collect dependencies first then computed value will consistent with watch
Curtion
2022-06-16 17:05:07 +08:00
@free9fw #1 我的问题其实是#5720 修复 computed 问题后,watch 的 cb 调用顺序却延后了,这个看起来不正常,没有找到文档可以参考预期行为是什么。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/860062

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX