Implementing a Custom onUnmounted Hook in Vue (TypeScript)
The onUnmounted lifecycle hook in Vue 3 allows you to run code when a component is unmounted from the DOM. This is crucial for cleaning up resources, canceling subscriptions, or performing any necessary actions before the component is destroyed. This challenge asks you to implement a simplified version of onUnmounted to solidify your understanding of Vue's lifecycle and reactivity system.
Problem Description
Your task is to create a custom hook called useUnmounted that mimics the functionality of Vue's built-in onUnmounted hook. This hook should accept a callback function as an argument and register it to be executed when the component using the hook is unmounted. The hook should be compatible with Vue 3's Composition API and written in TypeScript.
Key Requirements:
- Hook Function: The function should be named
useUnmounted. - Callback Registration: It should accept a single argument: a callback function.
- Execution on Unmount: The provided callback function should be executed when the component is unmounted.
- TypeScript: The code must be written in TypeScript, ensuring type safety.
- No External Dependencies: You should not use any external libraries beyond Vue itself.
- Reactivity Compatibility: The hook should be compatible with Vue's reactivity system.
Expected Behavior:
When a component using useUnmounted is unmounted, the callback function passed to the hook should be invoked. The callback should execute in the component's scope, allowing it to access component data and methods.
Edge Cases to Consider:
- Multiple Calls: What happens if
useUnmountedis called multiple times within the same component? Should the callback be registered multiple times, or should subsequent calls be ignored? (For simplicity, assume subsequent calls should be ignored). - Component Updates: The callback should only be executed on unmount, not during component updates.
- Asynchronous Callbacks: The callback might be asynchronous (e.g., using
setTimeoutorPromise). Ensure the unmount logic handles this correctly.
Examples
Example 1:
// Component: MyComponent.vue
<script setup lang="ts">
import { onUnmounted, ref } from 'vue';
const message = ref('Hello');
const useUnmounted = (callback: () => void) => {
onUnmounted(callback);
};
useUnmounted(() => {
console.log('Component unmounted!');
});
</script>
<template>
<div>{{ message }}</div>
</template>
Output:
// Console output when MyComponent is unmounted:
Component unmounted!
Explanation: When MyComponent is unmounted, the callback function registered with useUnmounted is executed, logging "Component unmounted!" to the console.
Example 2:
// Component: AnotherComponent.vue
<script setup lang="ts">
import { ref, onUnmounted } from 'vue';
const useUnmounted = (callback: () => void) => {
onUnmounted(callback);
};
const counter = ref(0);
useUnmounted(() => {
counter.value = -1; // Reset counter on unmount
console.log('Counter reset to -1 on unmount.');
});
// Component updates, counter.value changes, but the callback is not triggered.
</script>
<template>
<div>Counter: {{ counter }}</div>
</template>
Output:
// Console output only when AnotherComponent is unmounted:
Counter reset to -1 on unmount.
Explanation: The callback is only executed when AnotherComponent is unmounted, resetting the counter and logging the message.
Constraints
- The solution must be written in TypeScript.
- The solution must be compatible with Vue 3's Composition API.
- The solution should not use any external libraries beyond Vue itself.
- The
useUnmountedhook should only register the callback once per component instance. Subsequent calls should be ignored. - The callback function should be executed synchronously on unmount.
Notes
- You'll need to leverage Vue's lifecycle hooks to achieve this. Consider how
onUnmountedis implemented internally. - Think about how to ensure the callback is executed in the correct scope (the component's scope).
- This is a simplified implementation. The actual
onUnmountedhook in Vue has additional features and optimizations, but this challenge focuses on the core functionality. - Focus on clarity and correctness. While performance is a consideration, prioritize a working and understandable solution.