Every Vue component goes through a series of lifecycle stages, and Vue exposes hooks that fire at key moments. In the Composition API these are functions like onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, and onUnmounted. The onMounted hook fires after the component has been added to the DOM, making it the right place for tasks that require access to the rendered DOM—such as fetching initial data, integrating with third-party libraries like charts or maps, attaching event listeners, or focusing an input via a template ref. Conversely, onUnmounted runs after the component has been removed, and it is the appropriate place to clean up those listeners, clear timers, cancel in-flight requests, or close WebSocket connections to prevent memory leaks.
Component communication begins with props, which are declared in script setup using the defineProps compiler macro. defineProps accepts a schema describing each prop's type, whether it is required, and a default value if optional. On the opposite side of the data flow, child components communicate upward to their parents by emitting events. In script setup, you obtain an emitter with defineEmits(['eventName']) and then call emit('eventName', payload). The parent listens with @eventName="handler". Emits can also be declared with an object syntax that includes a validation function, and a false return value triggers a development-mode warning to help catch mistakes.
Beyond props and events, script setup components are closed by default, meaning parents cannot reach into a child to read its internal state. To selectively expose bindings, the child uses the defineExpose macro to explicitly publish properties or methods. On the parent side, a template ref can be declared with ref(null) and attached to a child component via ref="myRef", giving access to whatever the child has exposed. This pattern is essential for building imperative component APIs, such as exposing a reset or validate method from a form component.