5

I have this watcher (inside <script setup>:

const form = reactive({
    body: '',
    image: ''
})

watch(() => form.image, () => {
    console.log(form.image)
})

which I want to expand to watch two reactive objects:

watch(() => (form.image, form.body), () => {
    console.log(form)
})

but this now only watches form.body. I've been trying to implement this question's answer, but it doesn't seem to work like my watcher with new and old values. I want the watcher to trigger, when both values are updated.

3 Answers 3

12

I figured something out. It'll trigger when both values are true. You can put your own conditions in there.

const form = reactive({
    body: '',
    image: ''
})

watch(() => [form.image, form.body], () => {
    if (form.image && form.body) {
        console.log(form)
    }
})
This seems to work for simple cases but when the code base gets large and using `global proxies` (like a reactive store) as well as using too many proxies, it can fail. I've tried it with 4 global proxies on a large project and it only triggered sometimes.

Like @tao suggested in the comments, if you're working with nested objects, you have to use { deep: true } in your watcher.

More about deep watchers in the vue docs.

Sign up to request clarification or add additional context in comments.

1 Comment

It works in all cases. If any of the watched array elements are non-primitive values (e.g: object, array, map) and you want to trigger the watch when their internal prop values change, you have to use { deep: true } as third param. By default, watch is shallow, for performance.
9

You need to call watch each time if you need multiple watchers:

watch(() => form.image, () => {
    console.log(form.image)
})
watch(() => form.body, () => {
    console.log(form.body)
})

if what you need is a watcher to watch the two then :

watch([() => form.image, () => form.body], 
([newImage, newBody], [prevImage, prevBody]) => {
    console.log(form.body, form.image)
})

if we take example on that answer : https://stackoverflow.com/a/45853349/8126784 from the question you linked

Comments

0

This can be done with watchEffect it will check the reactivity:

watchEffect(() => {
  emit('update:selectedProduct', localSelectedProduct.value);
  emit('update:selectedOffer', localSelectedOffer.value);
});

Here's the vuejs docs: https://vuejs.org/guide/essentials/watchers.html#watcheffect

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.