vue3传入ref值没有被深层次监听?

VUE3官方文档写直接给 watch() 传入一个响应式对象,会隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发。但在以下例子中,监听函数并没有被触发。

const testObj = ref({ a: { b: { c: 1 } } });
watch(testObj, () => {
  console.log(testObj.value.a.b.c, "testObj.value.a.b.c");
});
setTimeout(() => {
  testObj.value.a.b.c = 2;
}, 2000);

经过我的实验,增加{deep:true}则会触发。
可是,传入一个响应式对象不是默认深层次监听的吗?

阅读 1.2k
avatarAI BotBETA

在 Vue 3 中,watch() 函数确实可以隐式地创建深层侦听器,但这并不意味着它会监听所有嵌套的属性变化。在 Vue 3 的响应式系统中,只有被直接访问的属性才会被认为是“依赖”的,从而被侦听。在你的例子中,虽然 testObj 是一个响应式对象,但 testObj.value.a.b.c 这个属性路径在 watch() 被调用时并没有被直接访问,因此 Vue 不会隐式地创建对它的深层侦听器。

要解决这个问题,你可以显式地指定 deep: true 选项来创建一个深层侦听器,就像你在实验中所做的那样。这将告诉 Vue 去侦听 testObj 对象中所有嵌套属性的变化。

所以,你的代码应该像这样:

const testObj = ref({ a: { b: { c: 1 } } });
watch(testObj, () => {
  console.log(testObj.value.a.b.c, "testObj.value.a.b.c");
}, { deep: true });
setTimeout(() => {
  testObj.value.a.b.c = 2;
}, 2000);

这样,无论 testObj 对象中的哪个嵌套属性发生变化,watch() 的回调函数都会被触发。

2 个回答

文档说的是reactive object
截屏2024-04-11 23.24.49.png
截屏2024-04-11 23.25.12.png

看文档时,如果有些概念不理解可以看英文版的,中文有时反而容易混淆

要对ref对象做深度监听,应该watch的是testObj.value

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题