Hone logo
Hone
Problems

Implementing onUpdated Hook in Vue.js with TypeScript

This challenge focuses on understanding and implementing the onUpdated lifecycle hook in Vue.js using TypeScript. You'll learn how to perform actions after a component's DOM has been updated, which is crucial for tasks like fetching data based on updated props, managing third-party library integrations with the DOM, or performing analytics.

Problem Description

Your task is to create a Vue component that utilizes the onUpdated lifecycle hook to respond to changes in its data or props. Specifically, you need to implement a mechanism that logs a message to the console whenever the component's DOM has finished updating due to a reactive change.

Key Requirements:

  1. Component Setup: Create a basic Vue 3 component using the Composition API and TypeScript.
  2. Reactive Data: The component should have at least one piece of reactive data that can be modified.
  3. onUpdated Hook: Implement the onUpdated hook within the component's setup function.
  4. Logging: Inside the onUpdated hook, log a specific message to the browser's console.
  5. Triggering Updates: Provide a way for the user to trigger changes to the reactive data (e.g., a button click).

Expected Behavior:

When the reactive data is modified and the component re-renders, the onUpdated hook should be called after the DOM has been updated. The console should then display your specified log message.

Edge Cases to Consider:

  • Initial Render: The onUpdated hook should not be called during the initial component render. It should only fire on subsequent updates.
  • Multiple Updates: If multiple reactive properties change rapidly, onUpdated should still fire after the DOM has settled from those updates.

Examples

Example 1:

// Component Template:
<template>
  <div>
    <p>{{ counter }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

// Component Script (TypeScript):
import { ref, onUpdated } from 'vue';

export default {
  setup() {
    const counter = ref(0);

    const increment = () => {
      counter.value++;
    };

    onUpdated(() => {
      console.log('Component DOM has been updated!');
    });

    return {
      counter,
      increment
    };
  }
};

Input: The user clicks the "Increment" button.

Output:

  1. The displayed counter value in the DOM updates from 0 to 1.
  2. The console logs: Component DOM has been updated!

Explanation: Clicking the button increments the counter ref. Vue detects this change, updates the DOM to reflect the new counter value, and then the onUpdated hook is triggered, logging the message.

Example 2:

Consider a scenario where a component receives a prop that changes.

// Parent Component Template:
<template>
  <MyComponent :message="dynamicMessage" />
  <button @click="changeMessage">Change Message</button>
</template>

<script lang="ts">
import { ref } from 'vue';
import MyComponent from './MyComponent.vue'; // Assume MyComponent is defined as in Example 1

export default {
  components: { MyComponent },
  setup() {
    const dynamicMessage = ref('Initial Message');

    const changeMessage = () => {
      dynamicMessage.value = 'Updated Message';
    };

    return {
      dynamicMessage,
      changeMessage
    };
  }
};
</script>

// MyComponent Script (TypeScript):
import { ref, onUpdated, defineProps } from 'vue';

const props = defineProps<{ message: string }>();

const counter = ref(0); // Local reactive data

const increment = () => {
  counter.value++;
};

onUpdated(() => {
  console.log(`MyComponent received new message: ${props.message} and counter updated to ${counter.value}`);
});

// ... rest of MyComponent setup

Input:

  1. The MyComponent is rendered with message: 'Initial Message'.
  2. The user clicks the "Change Message" button in the parent.

Output:

  1. The MyComponent will re-render.
  2. The console logs: MyComponent received new message: Updated Message and counter updated to 0 (assuming counter wasn't incremented). If the user also clicked "Increment" before "Change Message", the counter value would reflect that.

Explanation: The parent component updates its dynamicMessage prop. Vue propagates this change to MyComponent. After MyComponent's DOM updates due to the new prop value, the onUpdated hook is called, logging the relevant information.

Constraints

  • You must use Vue 3 with the Composition API.
  • The solution must be written entirely in TypeScript.
  • The onUpdated hook must be implemented using the onUpdated function from Vue's reactivity module.
  • The log message in onUpdated should be clearly identifiable as coming from this hook (e.g., "Component DOM has been updated!").
  • The component should be a single-file component (.vue file).

Notes

  • Remember that onUpdated fires after the DOM has been patched.
  • Distinguish onUpdated from onMounted (which fires once after the initial render) and onBeforeUpdate (which fires before the DOM is patched).
  • Consider how you might pass data into the onUpdated hook if needed, perhaps by accessing other reactive state within the setup function.
  • This exercise is a building block for more complex scenarios where reacting to DOM changes is essential.
Loading editor...
typescript