Vue 3 introduces a funtcional approach to reusing component logic through hooks, addressing limitations found in Vue 2's mixins and higher-order components. Hooks enable grouping related state and behavior into reusable functions, improving clarity and maintainability.
Core Concepts of Vue 3 Hooks
Hooks in Vue 3 are plain JavaScript functions built around the Composition API. They leverage utilities such as ref, reactive, and lifecycle triggers like onMounted to encapsulate logic independently of component instances.
Basic Hook Usage
Using the Setup Entry Point
import { ref, onMounted } from 'vue';
export default {
setup() {
const tally = ref(0);
onMounted(() => {
console.log('Component mounted');
});
return { tally };
}
};
The setup function acts as the composition context where reactive data and side effects are declared before being exposed to the template.
Lifecycle Hook Integration
Mounting Phase Triggger
import { onMounted } from 'vue';
onMounted(() => {
console.log('Component entered mounted stage');
});
Reactive Update Detection
import { onUpdated } from 'vue';
onUpdated(() => {
console.log('Component updated due to DOM or state change');
});
These hooks align component behavior with specific points in its lifecycle, ensuring precise control over initialization and updates.
Building Custom Reusable Hooks
Extract recurring patterns into self-contained functions:
import { ref, onMounted } from 'vue';
export function useIncrementer() {
const value = ref(0);
onMounted(() => {
console.log('Incrementer initialized');
});
const stepUp = () => { value.value += 1; };
return { value, stepUp };
}
Such custom hooks can be imported across components, eliminating duplication and centralizing related logic.
Advanced Composition Patterns
Combine multiple Composition API utilities for richer functionality:
import { ref, computed, watch } from 'vue';
export default {
setup() {
const num = ref(0);
const doubled = computed(() => num.value * 2);
watch(num, (next, prev) => {
console.log(`Value shifted from ${prev} to ${next}`);
});
return { num, doubled };
}
};
Here, computed creates derived state reactively, while watch observes changes to trigger side effects.
Practical Benefits and Guidelines
- Reusability: Encapsulated hooks remove the need for mixin name clashes and prop drilling associated with higher-order components.
- Readability: Grouped logic within a hook maps directly to a single concern, making component code easier to follow.
- Maintainability: Changes to shared behavior are localized to one hook file rather than scattered across components.
Guidelines:
- Prefer defining logic inside
setupto keep declarations close to usage. - Organize cohesive pieces of functionality into named custom hooks (
useXnaming convention). - Integrate lifecycle hooks and reactive primitives to precisely manage state transitions and side effects.