vue icon indicating copy to clipboard operation
vue copied to clipboard

Watch with getter doesn't react on object property (with ref)

Open TheEvilCoder42 opened this issue 1 year ago • 7 comments

Version

2.7.8

Reproduction link

codesandbox.io

Steps to reproduce

Change the text in the first (testRefObj) input field.

Watch using a getter on an object property made reactive using ref()

What is expected?

Console should log watch testRefObj.text + the changed text. Same as the second input (string). (In component HelloWorld.vue)

What is actually happening?

Only watch deep testRefObj gets logged (watch with deep: true on whole object, instead of a single property by getter)


It's stated here to use a getter to watch on a single property of an object, but this doesn't work: https://vuejs.org/guide/essentials/watchers.html#watch-source-types

deep: true is a workaround, but on objects with complex structures and more data, this will result in performance issues.

TheEvilCoder42 avatar Jul 28 '22 22:07 TheEvilCoder42

Maybe you should watch the () => testRefObj.value.text.

nooooooom avatar Aug 05 '22 03:08 nooooooom

() => testRefObj.value.text it would be appear error! He should be use const testRefObj= reactive({text:''}) and watch(() => testRefObj.text,value => {/* ... */}) and more https://vuejs.org/api/reactivity-core.html#watch

Jackllllll avatar Aug 05 '22 03:08 Jackllllll

@Jackllllll Seems you're right, it works with reactive() (updated example). Maybe I didn't understand the difference to ref(), I thought that I can't update the object (which I need to), but apart from not using the .value syntax, it seems to work. But ref() should just call reactive() on an object, as stated here: https://vuejs.org/guide/essentials/reactivity-fundamentals.html#reactive-variables-with-ref So maybe that's the real error here.

TheEvilCoder42 avatar Aug 05 '22 09:08 TheEvilCoder42

Hey, ref is just a nested layer of responsive value compared to reactive, the important thing is not whether to use ref or reactive to define the value, but how you can make watch subscribe to it.

In the case, the get of text is wrong, you should get the value defined on ref by testRefObj.value.text.

nooooooom avatar Aug 05 '22 10:08 nooooooom

@nooooooom I was quite sure this would give an error (since it's not "reactive" - like @Jackllllll said), but actually it does work. Seems this should be mentioned in the docs.

TheEvilCoder42 avatar Aug 05 '22 10:08 TheEvilCoder42

@nooooooom u can try own ide! To verify it's right by example of codesandbox.io

Jackllllll avatar Aug 05 '22 10:08 Jackllllll

@Jackllllll I updated the example with the suggestion from @nooooooom and it does work 👍

TheEvilCoder42 avatar Aug 05 '22 10:08 TheEvilCoder42

This seems to be a misunderstanding so there's nothing to fix here.

yyx990803 avatar Aug 18 '22 10:08 yyx990803