Ciclos de vida en Vue: guía práctica y cuándo usar cada hook
Por qué esto importa
Entender el ciclo de vida de un componente te permite saber exactamente cuándo ejecutar cada tipo de lógica: inicialización, acceso al DOM, sincronización con API, limpieza de efectos secundarios o depuración.
Concepto clave
Un componente en Vue 3 atraviesa varias fases:
- Creación
- Montaje
- Actualización
- Desmontaje
Además, existen hooks especiales para:
- Componentes cacheados con
<KeepAlive> - Manejo de errores
- Depuración del sistema reactivo
- SSR (Server-Side Rendering)
En las siguientes secciones veremos cuándo se ejecuta cada hook y para qué sirve, con ejemplos.
Creación del componente
En esta fase Vue crea la instancia del componente y configura la reactividad, pero todavía no existe el DOM.
Aquí normalmente se inicializa estado, configuración o llamadas iniciales.
beforeCreate
Se ejecuta antes de que Vue configure la reactividad.
<script>
export default {
beforeCreate() {
console.log('El componente está iniciando')
}
}
</script>No es posible usar
beforeCreateen Composition API, ya quesetup()se ejecuta antes de cualquier otro hook.
created
El estado reactivo ya está disponible, pero el DOM aún no existe.
Se suele usar para:
- Llamadas HTTP
- Inicializar estado
- Preparar lógica de negocio
<script>
export default {
data() {
return {
users: []
}
},
async created() {
this.users = await fetch('/api/users').then(r => r.json())
}
}
</script>No es posible usar
createden Composition API, ya quesetup()se ejecuta antes de cualquier otro hook.
setup()
Es el punto de entrada principal en Composition API.
Aquí se define:
- Estado reactivo
- Composables
- Watchers
- Lógica inicial del componente
<script setup>
import { ref } from 'vue'
const count = ref(0)
console.log('Setup ejecutado')
</script>No es posible usar
setup()en Options API, ya que es exclusivo de Composition API.
Montaje del componente
En esta fase Vue crea e inserta el DOM del componente.
Aquí ya es seguro usar:
- API del navegador
- Librerías externas
- Manipulación del DOM
onBeforeMount / beforeMount
Se ejecuta justo antes de insertar el DOM en la página.
No es muy común usarlo, pero puede servir para lógica previa al render final.
<script setup>
import { onBeforeMount } from 'vue'
onBeforeMount(() => {
console.log('El componente está por montarse')
})
</script><script>
export default {
beforeMount() {
console.log('Antes de montar el componente')
}
}
</script>onMounted / mounted
Se ejecuta después de que el componente fue insertado en el DOM.
Este es uno de los hooks más usados.
Usos típicos:
- Inicializar charts
- Registrar listeners
- Enfocar inputs
- Integrar librerías externas
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
console.log('Componente montado en el DOM')
})
</script><script>
export default {
mounted() {
console.log('Componente montado')
}
}
</script>Actualización del componente
Cuando cambia el estado reactivo, Vue vuelve a renderizar el componente.
Estos hooks permiten reaccionar antes o después de que el DOM cambie.
onBeforeUpdate / beforeUpdate
Se ejecuta antes de que Vue actualice el DOM.
Puede usarse para inspeccionar el estado previo.
<script setup>
import { onBeforeUpdate } from 'vue'
onBeforeUpdate(() => {
console.log('Antes de actualizar el DOM')
})
</script><script>
export default {
beforeUpdate() {
console.log('Antes del update')
}
}
</script>onUpdated / updated
Se ejecuta después de que Vue actualiza el DOM.
Útil cuando necesitas medir o interactuar con el DOM actualizado.
⚠️ No debe usarse como reemplazo de
watch.
<script setup>
import { onUpdated } from 'vue'
onUpdated(() => {
console.log('El DOM ya fue actualizado')
})
</script><script>
export default {
updated() {
console.log('DOM actualizado')
}
}
</script>Desmontaje del componente
Cuando un componente deja de existir, Vue ejecuta hooks de limpieza.
Esto es clave para evitar fugas de memoria.
onBeforeUnmount / beforeUnmount
Se ejecuta justo antes de destruir el componente.
<script setup>
import { onBeforeUnmount } from 'vue'
onBeforeUnmount(() => {
console.log('El componente será destruido')
})
</script><script>
export default {
beforeUnmount() {
console.log('Antes de desmontar')
}
}
</script>onUnmounted / unmounted
Se ejecuta después de que el componente fue destruido.
Ideal para limpiar:
- Timers
- Sockets
- Event listeners
<script setup>
import { onMounted, onUnmounted } from 'vue'
let timer
onMounted(() => {
timer = setInterval(() => {
console.log('tick')
}, 1000)
})
onUnmounted(() => {
clearInterval(timer)
})
</script><script>
export default {
mounted() {
this.timer = setInterval(() => {
console.log('tick')
}, 1000)
},
unmounted() {
clearInterval(this.timer)
}
}
</script>Hooks de <KeepAlive>
Cuando un componente está dentro de <KeepAlive>, no se destruye, solo se activa o desactiva.
onActivated / activated
Se ejecuta cuando el componente vuelve a mostrarse.
<script setup>
import { onActivated } from 'vue'
onActivated(() => {
console.log('Componente reactivado')
})
</script><script>
export default {
activated() {
console.log('Componente reactivado')
}
}
</script>onDeactivated / deactivated
Se ejecuta cuando el componente se oculta, pero sigue en memoria.
<script setup>
import { onDeactivated } from 'vue'
onDeactivated(() => {
console.log('Componente desactivado')
})
</script><script>
export default {
deactivated() {
console.log('Componente desactivado')
}
}
</script>Manejo de errores
onErrorCaptured / errorCaptured
Permite capturar errores de componentes hijos.
<script setup>
import { onErrorCaptured } from 'vue'
onErrorCaptured((error) => {
console.error('Error capturado:', error)
return false
})
</script><script>
export default {
errorCaptured(error) {
console.error('Error capturado:', error)
return false
}
}
</script>Hooks de depuración del render
Estos hooks ayudan a entender por qué un componente se vuelve a renderizar.
No deben usarse normalmente en producción.
onRenderTracked
Se ejecuta cuando Vue rastrea una dependencia reactiva durante el render.
<script setup>
import { onRenderTracked } from 'vue'
onRenderTracked((event) => {
console.debug('Dependencia rastreada:', event.key)
})
</script><script>
export default {
renderTracked(event) {
console.debug('Dependencia rastreada:', event.key)
}
}
</script>onRenderTriggered
Se ejecuta cuando una dependencia dispara un re-render.
<script setup>
import { onRenderTriggered } from 'vue'
onRenderTriggered((event) => {
console.debug('Re-render causado por:', event.key)
})
</script><script>
export default {
renderTriggered(event) {
console.debug('Re-render causado por:', event.key)
}
}
</script>SSR (Server Side Rendering)
onServerPrefetch / serverPrefetch
Permite cargar datos antes de renderizar el HTML en el servidor.
Esto evita pantallas vacías durante el primer render.
<script setup>
import { onServerPrefetch } from 'vue'
onServerPrefetch(async () => {
await fetch('/api/data')
})
</script><script>
export default {
async serverPrefetch() {
await fetch('/api/data')
}
}
</script>Cuándo usar hooks (y cuándo no)
Úsalos cuando:
- Necesitas acceder al DOM real (
onMounted) - Haces limpieza de recursos (
onUnmounted) - Trabajas con SSR (
onServerPrefetch) - Necesitas reaccionar a fases del ciclo del componente
Evítalos cuando:
- Un
computedresuelve el problema - Un
watches suficiente - Solo quieres reaccionar a cambios de estado específicos
Los hooks coordinan momentos del ciclo, no deberían contener toda la lógica del componente.
Resumen
Los hooks del ciclo de vida permiten controlar momentos clave del componente:
| Fase | Hooks principales |
|---|---|
| Creación | setup, created |
| Montaje | onMounted, mounted |
| Actualización | onUpdated, updated |
| Desmontaje | onUnmounted, unmounted |
| Cache | onActivated, onDeactivated |
| SSR | onServerPrefetch |
Si dudas qué hook usar, pregúntate primero: ¿En qué momento de la vida del componente necesito ejecutar esta lógica?
