Bird
Raised Fist0
Vueframework~20 mins

Watchers for side effects in Vue - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Vue Watcher Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What happens when the watched property changes?
Consider this Vue 3 component using the Composition API. What will be logged to the console when the count value changes from 0 to 1?
Vue
import { ref, watch } from 'vue';

export default {
  setup() {
    const count = ref(0);
    watch(count, (newVal, oldVal) => {
      console.log(`Count changed from ${oldVal} to ${newVal}`);
    });
    return { count };
  }
};
ALogs: 'Count changed from 0 to 1'
BLogs: 'Count changed from 1 to 0'
CNo log output because watch is not triggered
DThrows a runtime error because watch is used incorrectly
Attempts:
2 left
💡 Hint
Remember that the watcher callback receives the new and old values in that order.
❓ state_output
intermediate
2:00remaining
What is the value of message after the watcher runs?
In this Vue 3 component, what will be the value of message after name changes from 'Alice' to 'Bob'?
Vue
import { ref, watch } from 'vue';

export default {
  setup() {
    const name = ref('Alice');
    const message = ref('');
    watch(name, (newName) => {
      message.value = `Hello, ${newName}!`;
    });
    return { name, message };
  }
};
A"Hello, !"
B"Hello, Alice!"
C"Hello, Bob!"
DAn empty string ""
Attempts:
2 left
💡 Hint
The watcher updates message whenever name changes.
📝 Syntax
advanced
2:00remaining
Which watcher syntax correctly watches multiple sources?
You want to watch two reactive refs a and b and run a callback when either changes. Which option uses the correct Vue 3 watcher syntax?
Vue
import { ref, watch } from 'vue';

const a = ref(1);
const b = ref(2);

// Which watcher is correct?
Awatch(a && b, (newVal, oldVal) => { console.log(newVal); });
Bwatch([a, b], ([newA, newB], [oldA, oldB]) => { console.log(newA, newB); });
Cwatch(a, b, (newA, newB) => { console.log(newA, newB); });
Dwatch({a, b}, (newVals, oldVals) => { console.log(newVals); });
Attempts:
2 left
💡 Hint
To watch multiple refs, pass an array of sources as the first argument.
🔧 Debug
advanced
2:00remaining
Why does this watcher not trigger on nested object property change?
Given this Vue 3 component, why does the watcher not run when user.name changes?
Vue
import { reactive, watch } from 'vue';

export default {
  setup() {
    const user = reactive({ name: 'Alice', age: 30 });
    watch(user, (newUser) => {
      console.log('User changed:', newUser);
    }, { deep: true });
    // Later in code:
    user.name = 'Bob';
    return { user };
  }
};
AThe user object is not reactive because ref() was not used.
BReactive objects cannot be watched in Vue 3.
CThe watcher callback is missing the old value parameter.
DThe watcher does not deep watch by default, so nested changes are ignored.
Attempts:
2 left
💡 Hint
By default, watchers do not track nested property changes unless specified.
🧠 Conceptual
expert
2:00remaining
What is the effect of immediate option in watchers?
In Vue 3, what happens when you add immediate: true to a watcher?
Vue
import { ref, watch } from 'vue';

const count = ref(0);
watch(count, (newVal, oldVal) => {
  console.log('Count changed:', newVal);
}, { immediate: true });
AThe watcher callback runs immediately with the current value, then on every change.
BThe watcher callback runs twice on every change.
CThe watcher callback runs only on changes, ignoring the initial value.
DThe watcher callback runs only once and never again.
Attempts:
2 left
💡 Hint
Immediate watchers run the callback once right after setup.

Practice

(1/5)
1. What is the main purpose of a watch in Vue?
easy
A. To run code when reactive data changes
B. To define a new component
C. To style elements dynamically
D. To create a template for HTML

Solution

  1. Step 1: Understand what watch does

    A watcher observes reactive data and triggers code when that data changes.
  2. Step 2: Compare options to watcher purpose

    Only To run code when reactive data changes describes running code on reactive data change, which matches watcher behavior.
  3. Final Answer:

    To run code when reactive data changes -> Option A
  4. Quick Check:

    Watcher = run code on data change [OK]
Hint: Watchers react to data changes by running code [OK]
Common Mistakes:
  • Confusing watchers with components
  • Thinking watchers style elements
  • Assuming watchers create templates
2. Which of the following is the correct syntax to watch a reactive variable count in Vue 3 Composition API?
easy
A. watch(count, (newVal, oldVal) => { console.log(newVal) })
B. watch({ count }, (newVal, oldVal) => { console.log(newVal) })
C. watch('count', (newVal, oldVal) => { console.log(newVal) })
D. watch(() => count, (newVal, oldVal) => { console.log(newVal) })

Solution

  1. Step 1: Recall Vue 3 watch syntax for reactive refs

    In Vue 3 Composition API, to watch a ref's value, you typically pass a getter function like watch(() => count, callback) or watch(() => count.value, callback). Passing the ref directly watches the ref object, not its value.
  2. Step 2: Check each option

    watch(count, ...) watches the ref object, not its value. watch({ count }, ...) passes an object, invalid. watch('count', ...) uses invalid string. watch(() => count, ...) watches the value returned by the function, which is the ref's value.
  3. Final Answer:

    watch(() => count, (newVal, oldVal) => { console.log(newVal) }) -> Option D
  4. Quick Check:

    Watch ref value with function source = watch(() => count, callback) [OK]
Hint: Pass a function returning the reactive value to watch [OK]
Common Mistakes:
  • Passing { count } object instead of ref
  • Using string 'count'
  • Passing ref object directly instead of function
3. Given the code below, what will be logged when count.value changes from 1 to 2?
import { ref, watch } from 'vue'
const count = ref(1)
watch(() => count.value, (newVal, oldVal) => {
  console.log(`Changed from ${oldVal} to ${newVal}`)
})
count.value = 2
medium
A. Changed from 1 to 2
B. Changed from 2 to 1
C. Changed from undefined to 2
D. No output

Solution

  1. Step 1: Understand watcher callback parameters

    The watcher callback receives newVal and oldVal representing the new and previous values of the watched source.
  2. Step 2: Trace the value change

    Initially, count.value is 1. When changed to 2, the watcher logs "Changed from 1 to 2".
  3. Final Answer:

    Changed from 1 to 2 -> Option A
  4. Quick Check:

    Old to new value logged = Changed from 1 to 2 [OK]
Hint: Watcher logs old and new values on change [OK]
Common Mistakes:
  • Mixing old and new values order
  • Expecting no output on value change
  • Confusing initial value as undefined
4. Identify the error in this watcher code snippet:
import { ref, watch } from 'vue'
const count = ref(0)
watch(count.value, (newVal) => {
  console.log(newVal)
})
medium
A. Callback function must have two parameters
B. Missing function to return count in watch source
C. Ref must be declared with reactive() instead of ref()
D. watch must be imported from 'vue-router'

Solution

  1. Step 1: Check watch source argument

    In Vue 3 Composition API, to watch a ref, you must pass a function returning the ref's value, like watch(() => count.value, callback).
  2. Step 2: Identify the error

    The code passes count.value directly, which is incorrect. It should be watch(() => count.value, ...).
  3. Final Answer:

    Missing function to return count in watch source -> Option B
  4. Quick Check:

    Watch source must be a function returning value [OK]
Hint: Watch source must be a function returning reactive value [OK]
Common Mistakes:
  • Passing count.value (primitive) directly instead of ref or getter
  • Thinking callback needs two parameters always
  • Importing watch from wrong package
5. You want to watch a reactive object user and run a side effect only when the user.name changes, ignoring other properties. Which watcher setup is correct?
hard
A. watch(() => user, (newUser) => { console.log('User changed:', newUser) }, { deep: true })
B. watch(user, (newUser) => { console.log('User changed:', newUser) })
C. watch(() => user.name, (newName) => { console.log('Name changed:', newName) })
D. watch('user.name', (newName) => { console.log('Name changed:', newName) })

Solution

  1. Step 1: Understand watching nested properties

    To watch a specific property like user.name, watch a function returning that property.
  2. Step 2: Evaluate options

    watch(() => user.name, (newName) => { console.log('Name changed:', newName) }) watches user.name directly, triggering only on name changes. watch(user, (newUser) => { console.log('User changed:', newUser) }) watches whole object, triggering on any change. watch(() => user, (newUser) => { console.log('User changed:', newUser) }, { deep: true }) watches whole object deeply, also triggers on any change. watch('user.name', (newName) => { console.log('Name changed:', newName) }) uses a string, which is invalid in Vue 3 Composition API.
  3. Final Answer:

    watch(() => user.name, (newName) => { console.log('Name changed:', newName) }) -> Option C
  4. Quick Check:

    Watch specific property with function source = watch(() => user.name, (newName) => { console.log('Name changed:', newName) }) [OK]
Hint: Watch specific property with a function returning it [OK]
Common Mistakes:
  • Watching whole object instead of property
  • Using string source instead of function
  • Using deep option unnecessarily
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard