Hone logo
Hone
Problems

Implement a Vue Watcher for Real-time Data Updates

This challenge focuses on implementing a fundamental Vue.js reactivity feature: watchers. You will create a watcher to monitor changes in a specific data property within a Vue component and execute a callback function when that property's value changes. This is crucial for performing side effects like API calls, updating other data, or logging based on data modifications.

Problem Description

Your task is to create a Vue component that demonstrates the use of the watch option in Vue 3 (Composition API using <script setup> or Options API). The component should have a data property that can be modified, and you need to set up a watcher to observe this property. When the property changes, the watcher's callback should be triggered, and it should perform a specific action.

Key Requirements:

  1. Vue Component: Create a Vue component (either using Options API or Composition API with <script setup>).
  2. Observable Data Property: Define a reactive data property within the component (e.g., a counter, a text input value).
  3. Watcher Implementation: Implement a watcher that targets the defined data property.
  4. Callback Function: The watcher's callback function should execute a predefined action. For this challenge, the action will be to log a message to the console indicating that the watched property has changed and display its new value.
  5. Triggering Changes: Provide a way for the user to modify the observable data property (e.g., a button to increment a counter, an input field to change text).

Expected Behavior:

When the user interacts with the component to change the observable data property, the watcher's callback should execute. The console should display a message similar to: "Watched property changed: [new value]".

Edge Cases to Consider:

  • Initial Value: How does the watcher behave when the component is first initialized? (By default, watchers don't run on initialization unless immediate: true is set).
  • Deep Watching (Optional but good to consider): If the watched property were an object or array, how would you ensure nested changes are detected?

Examples

Example 1: Counter Component

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  data() {
    return {
      count: 0,
    };
  },
  watch: {
    count(newValue: number, oldValue: number) {
      console.log(`Count changed from ${oldValue} to ${newValue}`);
      console.log(`The new count is: ${newValue}`);
    },
  },
  methods: {
    increment() {
      this.count++;
    },
  },
});
</script>

Input: The user clicks the "Increment" button three times.

Output (Console Logs):

Count changed from 0 to 1
The new count is: 1
Count changed from 1 to 2
The new count is: 2
Count changed from 2 to 3
The new count is: 3

Explanation: Each click on the "Increment" button updates the count data property. The watcher detects this change and logs the old and new values to the console.

Example 2: Text Input Component (Composition API)

<template>
  <div>
    <input type="text" v-model="message" placeholder="Type something...">
    <p>Message: {{ message }}</p>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';

const message = ref<string>('');

watch(message, (newValue: string, oldValue: string) => {
  console.log(`Message changed from "${oldValue}" to "${newValue}"`);
  console.log(`The current message is: ${newValue}`);
});
</script>

Input: The user types "Hello Vue" into the input field.

Output (Console Logs):

Message changed from "" to "H"
The current message is: H
Message changed from "H" to "He"
The current message is: He
Message changed from "He" to "Hel"
The current message is: Hel
Message changed from "Hel" to "Hell"
The current message is: Hell
Message changed from "Hell" to "Hello"
The current message is: Hello
Message changed from "Hello" to "Hello "
The current message is: Hello
Message changed from "Hello " to "Hello V"
The current message is: Hello V
Message changed from "Hello V" to "Hello Vu"
The current message is: Hello Vu
Message changed from "Hello Vu" to "Hello Vue"
The current message is: Hello Vue

Explanation: As the user types each character, the message ref is updated. The watcher intercepts these updates and logs the changes to the console. Note that the watcher fires for each character typed.

Constraints

  • Your solution must be written in TypeScript.
  • You should use either the Options API or the Composition API (<script setup>) of Vue 3.
  • The watcher callback should log to the browser's console.
  • The example components provided are for demonstration; you are free to implement your own component structure as long as the core watcher functionality is present and observable.

Notes

  • Consider how you might handle watching object properties or arrays. While not strictly required for this challenge, it's a common scenario. You might explore the deep option for watchers.
  • Think about the difference between watch and watchEffect. For this challenge, watch is the intended tool to observe specific properties.
  • Ensure your TypeScript types are correctly applied to the watched properties and their new/old values within the callback.
Loading editor...
typescript