Ciclos de vida en Vue: fase de creación (beforeCreate, created, setup)
Cuando empiezas a escribir un componente en Vue, una de las preguntas más comunes es: ¿dónde debería colocar la lógica inicial?
La respuesta depende principalmente de si estás trabajando con Options API o con Composition API.
La fase de creación es el momento en el que Vue construye la instancia del componente, inicializa su sistema de reactividad y prepara su estado interno. En esta etapa, el componente todavía no ha sido montado en el DOM.
Qué ocurre en esta fase
En términos prácticos, el orden clásico del ciclo de vida con Options API es:
beforeCreatecreated- montaje (
beforeMount/mounted)
Con Composition API, el punto de entrada es setup(), que se ejecuta antes de los hooks de ciclo de vida de Options API, incluidos beforeCreate y created.
Si quieres quedarte con una idea simple:
beforeCreate→ punto extremadamente temprano; rara vez necesario hoy.created→ estado reactivo disponible en Options API.setup→ punto de arranque principal en Composition API.
beforeCreate: cuándo aparece y por qué casi no se usa
beforeCreate se ejecuta antes de que Vue termine de inicializar el estado reactivo y las opciones de la instancia.
En este punto:
datacomputedmethods
Todavía no están inicializados, por lo que el acceso a la instancia es muy limitado.
Por esta razón, en proyectos modernos con Vue 3 este hook rara vez se utiliza. En la mayoría de casos aparece únicamente en código legado o escenarios muy específicos relacionados con plugins o extensiones del framework.
<script>
export default {
beforeCreate() {
console.log('El componente está arrancando')
}
}
</script>created: el punto útil en Options API
En el hook created, la instancia del componente ya está completamente inicializada en términos de estado reactivo y métodos, aunque el DOM todavía no ha sido renderizado.
Esto lo convierte en un buen lugar para:
- Inicializar estado derivado de configuración.
- Cargar datos de forma temprana.
- Preparar timers o listeners que no dependan del DOM.
<script>
export default {
data() {
return {
users: []
}
},
async created() {
this.users = await fetch('/api/users').then((r) => r.json())
}
}
</script>setup: el arranque natural en Vue 3
Cuando trabajas con Composition API, setup() es el verdadero punto de entrada del componente.
Dentro de setup defines:
refreactivecomputedwatch- composables
Además, setup se ejecuta antes de que el componente sea montado, por lo que permite preparar todo el estado que la vista necesitará en su primer render.
<script setup>
import { ref, computed } from 'vue'
const count = ref(0)
const double = computed(() => count.value * 2)
console.log('setup ejecutado')
</script>
<template>
<button @click="count++">
count: {{ count }} / double: {{ double }}
</button>
</template>Comparación rápida: beforeCreate vs created vs setup
| Punto | API | Qué ya tienes disponible | Cuándo elegirlo |
|---|---|---|---|
beforeCreate | Options | Instancia en arranque temprano | Casos muy puntuales o código legado |
created | Options | Estado y métodos disponibles, sin DOM | Inicialización de datos o lógica sin DOM |
setup | Composition | Reactividad y composables desde el inicio | Opción principal en Vue 3 moderno |
Errores que se repiten con frecuencia
1) Intentar manipular el DOM en created o al inicio de setup
Ni created ni el inicio de setup garantizan que el DOM exista.
Si necesitas interactuar con elementos reales del DOM, debes usar:
mounted(Options API)onMounted(Composition API)
2) Usar beforeCreate por costumbre
Muchos ejemplos antiguos de Vue lo utilizan, pero en Vue 3 rara vez aporta ventajas reales frente a setup (Composition API) o created (Options API).
3) Mezclar mentalmente Options API y Composition API
Vue permite combinar ambas API en un proyecto, pero dentro de un componente conviene tener claro cuál es el punto de entrada principal. Mezclar ambas sin un criterio claro puede terminar duplicando lógica de inicialización.
Un ejemplo equivalente en ambos estilos
Supongamos que queremos cargar usuarios cuando se crea el componente, sin depender del DOM.
<script setup>
import { ref } from 'vue'
const users = ref([])
async function loadUsers() {
users.value = await fetch('/api/users').then((r) => r.json())
}
// Se ejecuta durante setup (fase de creación)
loadUsers()
</script>
<template>
<ul>
<li v-for="user in users" :key="user.id">
{{ user.name }}
</li>
</ul>
</template><script>
export default {
data() {
return {
users: []
}
},
async created() {
this.users = await fetch('/api/users').then((r) => r.json())
}
}
</script>
<template>
<ul>
<li v-for="user in users" :key="user.id">
{{ user.name }}
</li>
</ul>
</template>Cierre
- En componentes modernos basados en Vue 3,
setupsuele ser el punto de entrada más claro y consistente para inicializar estado y lógica. - Si trabajas en componentes escritos con Options API, el hook
createdsigue siendo completamente válido para inicialización que no depende del DOM. - En cambio,
beforeCreateha quedado como una pieza más histórica que práctica en la mayoría de proyectos actuales.
