InterviewHack.ai
Empezar gratis
Blog/Preguntas de entrevista de Vue.js con respuestas (35+)

Preguntas de entrevista de Vue.js con respuestas (35+)

16 de septiembre de 2026

vuejavascript

Artículo completo "Preguntas de entrevista de Vue.js con respuestas (35+)" — recurso técnico para devs hispanohablantes que preparan entrevistas Vue.js, con 45 preguntas numeradas, respuestas detalladas y código real.

Preguntas de entrevista de Vue.js con respuestas (35+)

¿Tenés una entrevista técnica de Vue.js y no sabés por dónde empezar? Esta guía tiene todo lo que necesitás: desde las preguntas que te hacen en el primer filtro hasta las que marcan la diferencia cuando competís por un rol senior.

Cubrimos Vue 2 y Vue 3, Composition API, Options API, Vuex, Pinia, Vue Router y patrones avanzados — con código real que podés leer, entender y reproducir en voz alta.


Índice

  1. 1[Fundamentos de Vue](#fundamentos)
  2. 2[Sistema de reactividad](#reactividad)
  3. 3[Composition API vs Options API](#composition-vs-options)
  4. 4[Componentes y comunicación](#componentes)
  5. 5[Vue Router](#router)
  6. 6[Estado global: Vuex y Pinia](#estado)
  7. 7[Rendimiento y optimización](#rendimiento)
  8. 8[Preguntas avanzadas](#avanzadas)

Fundamentos de Vue {#fundamentos}

1. ¿Qué es Vue.js y qué lo diferencia de React o Angular?

Vue es un framework JavaScript progresivo para construir interfaces de usuario. "Progresivo" significa que podés adoptarlo gradualmente: desde sprinkles de interactividad en una página existente hasta una SPA completa.

Diferencias clave:

| | Vue | React | Angular |

|---|---|---|---|

| Curva de aprendizaje | Baja | Media | Alta |

| Opinionado | Medio | Poco | Mucho |

| Templates | HTML-like | JSX | HTML + directivas |

| Estado | Reactivo built-in | useState / libs externas | Services + RxJS |

Vue combina lo mejor de React (component model) y Angular (directivas declarativas en templates) con una sintaxis más accesible. Su sistema de reactividad es automático — no necesitás llamar a setState ni suscribirte manualmente a observables.


2. ¿Qué es el Virtual DOM y cómo lo usa Vue?

El Virtual DOM es una representación en memoria del DOM real. Cuando el estado cambia, Vue construye un nuevo árbol virtual, lo compara con el anterior (diffing) y solo actualiza los nodos del DOM real que cambiaron (patching).

javascript
// Vos escribís esto:
const count = ref(0)

// Vue internamente hace algo así:
const vnode = {
  type: 'div',
  props: {},
  children: [`El contador está en ${count.value}`]
}

Importante para la entrevista: Vue 3 introdujo un compilador más inteligente que marca los nodos estáticos y los salta completamente durante el diffing. Esto se llama static hoisting y es una de las razones por las que Vue 3 es significativamente más rápido que Vue 2.


3. ¿Cuáles son los lifecycle hooks principales en Vue?

Vue 3 (Composition API):

javascript
import { onMounted, onUpdated, onUnmounted, onBeforeMount } from 'vue'

export default {
  setup() {
    onBeforeMount(() => {
      // El componente está por montarse, el DOM no existe todavía
    })

    onMounted(() => {
      // El DOM ya existe — acá podés acceder a refs del template
      // Ideal para llamadas a APIs, inicializar librerías de terceros
    })

    onUpdated(() => {
      // El componente se re-renderizó porque el estado cambió
      // Ojo: no mutés estado acá o entrás en loop infinito
    })

    onUnmounted(() => {
      // El componente se desmontó — limpiá event listeners, timers, websockets
    })
  }
}

Vue 2 / Options API:

javascript
export default {
  beforeCreate() {},
  created() {},      // Estado inicializado, sin DOM
  beforeMount() {},
  mounted() {},      // Equivalente a onMounted
  beforeUpdate() {},
  updated() {},
  beforeDestroy() {}, // Equivalente a onUnmounted
  destroyed() {}
}

En la entrevista te pueden preguntar: "¿En qué lifecycle hook harías una llamada a una API?" La respuesta correcta es onMounted (o mounted), porque es cuando el componente ya está en el DOM y el usuario espera ver datos. En created también funciona, pero el DOM no está disponible.


4. ¿Qué es `v-model` y cómo funciona internamente?

v-model es azúcar sintáctico para binding bidireccional. En un input, es equivalente a:

html
<!-- Esto: -->
<input v-model="nombre" />

<!-- Es lo mismo que esto: -->
<input :value="nombre" @input="nombre = $event.target.value" />

En componentes custom, v-model pasa un prop modelValue y escucha el evento update:modelValue:

javascript
// Componente hijo: MiInput.vue
export default {
  props: ['modelValue'],
  emits: ['update:modelValue'],
  template: `
    <input 
      :value="modelValue" 
      @input="$emit('update:modelValue', $event.target.value)"
    />
  `
}
html
<!-- Componente padre -->
<MiInput v-model="nombre" />

Vue 3 permite múltiples v-models en el mismo componente:

html
<MiFormulario v-model:nombre="nombre" v-model:email="email" />

5. Explicá la diferencia entre `v-show` y `v-if`

html
<!-- v-if: agrega/elimina el elemento del DOM -->
<div v-if="visible">Este div aparece y desaparece del DOM</div>

<!-- v-show: siempre está en el DOM, solo cambia display: none -->
<div v-show="visible">Este div siempre existe</div>

Cuándo usar cada uno:

  • v-if: cuando la condición rara vez cambia o el elemento es costoso de inicializar. El renderizado inicial es más barato si la condición es false.
  • v-show: cuando toggleás frecuentemente. El elemento siempre está en el DOM, así que el toggle es un cambio de CSS, no un mount/unmount completo.

Regla práctica: modales que se abren una vez → v-if. Tabs que el usuario alterna constantemente → v-show.


6. ¿Qué es la directiva `v-for` y cuál es la importancia del atributo `key`?

html
<ul>
  <li v-for="(item, index) in lista" :key="item.id">
    {{ index + 1 }}. {{ item.nombre }}
  </li>
</ul>

El atributo :key le dice a Vue cómo identificar cada elemento cuando la lista cambia. Sin él, Vue usa el algoritmo de diffing más simple (por posición), lo que puede causar bugs con componentes que tienen estado interno.

Ejemplo del problema sin key:

html
<!-- ❌ Sin key: si reordenás la lista, el checkbox del elemento A
     puede quedar pegado al texto del elemento B -->
<li v-for="item in lista">
  <input type="checkbox" /> {{ item.nombre }}
</li>

<!-- ✅ Con key: Vue sabe exactamente qué elemento es cuál -->
<li v-for="item in lista" :key="item.id">
  <input type="checkbox" /> {{ item.nombre }}
</li>

Regla: nunca uses el index como key si el orden de la lista puede cambiar. Usá siempre un identificador único del dato (como item.id).


Sistema de reactividad {#reactividad}

7. ¿Cómo funciona el sistema de reactividad de Vue 3?

Vue 3 usa Proxies de JavaScript para interceptar lecturas y escrituras de propiedades. Cuando leés una propiedad reactiva dentro de un efecto (como computed, watch, o el render), Vue registra esa dependencia. Cuando la propiedad cambia, Vue re-ejecuta todos los efectos que la usaban.

javascript
import { reactive, ref, effect } from 'vue'

const estado = reactive({ count: 0 })

// effect() es la base de computed, watch y el render
effect(() => {
  console.log('El count es:', estado.count) // Se ejecuta ahora...
})

estado.count++ // ...y también acá, porque la dependencia fue rastreada

Vue 2 usaba Object.defineProperty, que tiene limitaciones:

  • No puede detectar adición/eliminación de propiedades nuevas
  • No puede detectar cambios en arrays por índice

Por eso en Vue 2 necesitabas Vue.set(obj, 'nuevaClave', valor). En Vue 3 con Proxy, eso ya no es necesario.


8. ¿Cuál es la diferencia entre `ref` y `reactive`?

javascript
import { ref, reactive } from 'vue'

// ref: para valores primitivos (y también objetos, aunque reactive es más natural)
const count = ref(0)
console.log(count.value) // 0 — accedés al valor con .value
count.value++

// reactive: para objetos y arrays
const usuario = reactive({
  nombre: 'Ana',
  edad: 28
})
console.log(usuario.nombre) // 'Ana' — sin .value
usuario.edad = 29

Diferencia crucial: reactive no puede ser reasignado completo:

javascript
// ❌ Esto rompe la reactividad
let usuario = reactive({ nombre: 'Ana' })
usuario = { nombre: 'Carlos' } // La referencia se perdió, Vue no lo puede rastrear

// ✅ Con ref, podés reasignar
let usuario = ref({ nombre: 'Ana' })
usuario.value = { nombre: 'Carlos' } // Esto sí funciona

Regla general: usá ref para todo (especialmente si venís de React). Usá reactive cuando tenés un objeto de estado bien definido y querés evitar el .value.


9. ¿Qué es `computed` y cuándo lo usás?

Un computed es un valor derivado que se recalcula automáticamente cuando sus dependencias cambian. Se cachea: si las dependencias no cambiaron, devuelve el valor anterior sin recalcular.

javascript
import { ref, computed } from 'vue'

const precio = ref(100)
const descuento = ref(0.1)

// computed: se recalcula solo cuando precio o descuento cambien
const precioFinal = computed(() => {
  console.log('Recalculando...') // Solo se ejecuta cuando cambia precio o descuento
  return precio.value * (1 - descuento.value)
})

console.log(precioFinal.value) // 90, y loguea "Recalculando..."
console.log(precioFinal.value) // 90, sin loguear (usó el caché)
precio.value = 200
console.log(precioFinal.value) // 180, y loguea "Recalculando..."

computed writable:

javascript
const fullName = computed({
  get() {
    return `${firstName.value} ${lastName.value}`
  },
  set(newValue) {
    const parts = newValue.split(' ')
    firstName.value = parts[0]
    lastName.value = parts[1]
  }
})

10. ¿Cuándo usás `watch` vs `watchEffect`?

javascript
import { ref, watch, watchEffect } from 'vue'

const query = ref('')
const resultados = ref([])

// watch: controlás exactamente qué observar y reaccionás al cambio
watch(query, async (nuevoValor, valorAnterior) => {
  if (nuevoValor.length > 2) {
    resultados.value = await buscar(nuevoValor)
  }
}, { immediate: false }) // immediate: true para ejecutar de entrada

// watchEffect: se ejecuta inmediatamente y rastrear dependencias automáticamente
watchEffect(async () => {
  // Acá se suscribe a TODAS las refs que lee
  if (query.value.length > 2) {
    resultados.value = await buscar(query.value)
  }
})

Cuándo usar cada uno:

| | watch | watchEffect |

|---|---|---|

| Acceso al valor anterior | Sí | No |

| Control explícito de qué observar | Sí | No (automático) |

| Ejecución inmediata por defecto | No | Sí |

| Mejor para | Side effects específicos, lazy | Side effects que dependen de varios valores |


Composition API vs Options API {#composition-vs-options}

11. ¿Cuál es la diferencia entre Options API y Composition API?

Options API organiza el código por tipo de opción (data, methods, computed, watch):

javascript
// Options API — Vue 2 y Vue 3
export default {
  data() {
    return {
      count: 0,
      nombre: ''
    }
  },
  computed: {
    countDoble() {
      return this.count * 2
    }
  },
  methods: {
    incrementar() {
      this.count++
    }
  },
  mounted() {
    console.log('Montado')
  }
}

Composition API organiza el código por lógica de negocio:

javascript
// Composition API — Vue 3
import { ref, computed, onMounted } from 'vue'

export default {
  setup() {
    // Toda la lógica del contador junta
    const count = ref(0)
    const countDoble = computed(() => count.value * 2)
    const incrementar = () => count.value++

    // Toda la lógica del usuario junta
    const nombre = ref('')
    // ... más lógica del usuario

    onMounted(() => console.log('Montado'))

    return { count, countDoble, incrementar, nombre }
  }
}

La ventaja real de Composition API: podés extraer lógica en composables (funciones reutilizables) y compartirla entre componentes sin mixins ni herencia:

javascript
// useContador.js — composable reutilizable
export function useContador(inicial = 0) {
  const count = ref(inicial)
  const incrementar = () => count.value++
  const resetear = () => count.value = inicial
  return { count, incrementar, resetear }
}

// En cualquier componente:
const { count, incrementar } = useContador(10)

12. ¿Qué es `<script setup>` y por qué se usa?