为什么Vue3 Composition API的watch的deep对直接传入的reactive无效,对reactive getter有效?
问题原因说明
这不是Vue框架的bug,是Vue3针对reactive类型监听源的默认设计行为,具体逻辑如下:
- 当watch的监听源直接传入reactive对象时,Vue会强制开启深度监听模式,你手动传入的
deep配置项会被直接忽略。
对应你测试用例里的表现就是:第一个没有配置deep: true的watch(state, ...)也触发了回调,第三个手动传入deep: true的监听表现和第一个完全一致,看起来就像deep配置没生效一样。 - 当watch的监听源传入的是返回reactive对象的getter函数(也就是
() => state这种写法)时,Vue默认只会监听getter返回值的引用是否发生变化,不会自动开启深度监听,此时你手动传入的deep配置才会正常生效。
对应你测试用例里的表现就是:第二个没有配置deep: true的watch(() => state, ...)没有触发回调,第四个配置了deep: true的getter监听正常触发了回调。
测试日志对应验证
你触发state.attrs.date = new Date()后控制台打印的三条日志完全符合上述逻辑:
- 第一条
non-deep日志:直接监听reactive对象,强制深度监听触发 - 第二条
deep日志:直接监听reactive对象,不管传没传deep参数都强制深度监听触发 - 第三条
deep getter日志:getter形式监听开启了deep: true,触发回调 - 未出现的
non-deep getter日志:getter形式未开启深度监听,仅监听引用变化,内部属性修改不会触发,符合预期
如果需要监听reactive对象且可自主控制是否开启深度监听,统一使用getter函数作为监听源即可。
内容的提问来源于stack exchange,提问作者Sicko Yang
相关产品推荐
相关产品推荐

