watch() on a ref obtained through toRefs() is not a deep watch
Vue version
3.3.4
Link to minimal reproduction
Steps to reproduce
In the reproduce setup, the parent component (App.vue) creates a reactive state, called anchor, and passes the state to two child components: Child.vue and Child2.vue.
These two child components are supposed to watch the changes on the anchor property, and update the text whenever anchor state has a change:
- Child (red) is the one with the bug, the text is not updating unless the watch made explicitly
{ deep: true }
- Child2 (green) is the correct one, wired up exactly the same as Child except the stuff being watched is
props.reference
instead of the reference inconst { reference } = toRefs(props)
;
What is expected?
According to the documentation, this watch in Child.vue should be deep by default, and the text driven by msg should update every second:
const { reference } = toRefs(props);
watch(
reference,
(val) => {
counter++;
msg.value = 'reference changed: ' + counter;
}
);
What is actually happening?
The Child.vue watch is not deep, and does not trigger when the parent component updates the anchor state. You have to explicitly make the watch deep in order to get it triggered properly.
System Info
No response
Any additional comments?
No response
According to the documentation, this watch in Child.vue should be deep by default
It should not be deep, which part of the documentation are you referring to?
I was referring to this: https://vuejs.org/guide/essentials/watchers.html#deep-watchers
But on a second look, it says “if you call watch directly on a reactive object” - does this mean the behavior literally applies only to things created using reactive(), not ref() of an object, or ref whose value is set to a reactive object?
Xinchao
On 26 Jul 2023, at 2:51 PM, Jacek Karczmarczyk @.***> wrote:
According to the documentation, this watch in Child.vue should be deep by default
It should not be deep, which part of the documentation are you referring to?
— Reply to this email directly, view it on GitHubhttps://github.com/vuejs/core/issues/8847#issuecomment-1651081852, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AIUJUJGJDQH62UVOXPV5RTTXSC46LANCNFSM6AAAAAA2YCYQ3U. You are receiving this because you authored the thread.Message ID: @.***>
Yes, see https://github.com/vuejs/core/blob/main/packages/runtime-core/src/apiWatch.ts#L208 It may be confusing indeed, if ref's value is an object then the value is a reactive object, probably wording in docs could be improved