在我的设置(Vue3)中,我有一个类方法,它将本地非反应性对象分配给反应性对象的属性。然后,它立即修改本地对象的属性。令人惊讶的是,尽管局部变量本身尚未与 Vue 的反应系统发生反应,但 Vue 观察程序仍能检测到这些变化。
<script setup>
import { reactive, watch } from 'vue';
class MyClass {
data = null;
assignAndUpdateImmediate() {
const local_variable = { name: 'Immediate: initial' };
this.data = local_variable;
// This local variable is not reactive, but changing it is reflected in the watcher
local_variable.name = 'Immediate: updated';
}
}
const reactiveObject = reactive(new MyClass());
watch(() => reactiveObject.data?.name, (newName, oldName) => {
console.log(`WATCHER: "${oldName}" -> "${newName}"`);
});
reactiveObject.assignAndUpdateImmediate();
</script>
<template>
</template>
输出:
WATCHER: "undefined" -> "Immediate: updated"
如果我们在分配反应成员之后和修改局部变量之前引入延迟,则更改不会像预期的那样反映在观察程序中。
输出:
WATCHER: "undefined" -> "Immediate: initial"
为什么在第一个示例中修改非反应性属性看起来是反应性的?
我确实理解分配 到local_variable
会this.data
触发观察器,并且 Vue 使用一些'tick'
-system 来避免不必要的频繁更新,但观察器中的值仍然应该是"Immediate: initial"
。
那是因为您使用回调手表,它会创建一个计算的。
在您的特定情况下,当您调用时,
reactiveObject.assignAndUpdateImmediate()
您可以在响应式this
和此特定行上调用它:作用于反应性对象并触发计算值重新计算以及相应的监视回调。
name
如果您在不访问的情况下更改,则reactiveObject
不会触发任何监视:VUE SFC 游乐场
手表与 watch(compulated(() =>reactiveObject.data?.name)) 相同。因此只有当依赖项更新时才会调用回调。在我们的例子中是这样的
reactiveObjec.data
(但不是.name
因为name
第一次回调调用时不存在)。依赖项是 VUE 第一次读取的内容。.name 肯定是第一次出现,所以它不会成为依赖项。第二次与任何异步代码都不重要:vuejs.org/guide/essentials/watchers.html#watcheffect
如果您
assign...()
再次调用并且不更改数据,则不会再次调用回调:VUE SFC 游乐场