Ilustración de un laboratorio de codificación mágica de Vue.js

¿Qué es la reactividad? La magia detrás de Vue.js explicada con claridad

Explora el sistema de reactividad de Vue.js, desde analogías simples hasta su implementación técnica con Proxies, y aprende a optimizar tus aplicaciones.

¿Qué es la reactividad? La magia detrás de Vue.js explicada con claridad

La reactividad es el corazón de Vue.js. Es lo que hace que la interfaz no sea un adorno bonito, sino un sistema vivo que responde a los cambios de estado sin que tú tengas que perseguir el DOM como si fuera 2012.

En este artículo vamos a desmontar el concepto sin misticismo innecesario: primero con una analogía simple, luego con lo que realmente ocurre a nivel técnico, y finalmente con buenas prácticas que te ahorrarán bugs y problemas de rendimiento.

La analogía: el efecto Excel

No necesitas un doctorado en ciencias de la computación para entender la reactividad. Basta con haber usado Excel sin romper nada.

Si en una celda C1 escribes la fórmula =A1 + B1, el valor de C1 se actualiza automáticamente cuando cambian A1 o B1. No haces clic en “refrescar”, no vuelves a escribir la fórmula. Simplemente ocurre.

Eso es reactividad: una relación automática entre datos y resultados.

Analogía del mundo real: imagina una cafetera inteligente. En el momento en que detecta que hay una taza colocada, el botón de iniciar se activa. No porque alguien lo programe cada vez, sino porque el sistema está atento al estado.

La evolución técnica: de Vue 2 a Vue 3

Vue no siempre tuvo el sistema de reactividad elegante que conocemos hoy. Entender su evolución ayuda a escribir mejor código y a no pelearse con el framework.

Vue 2: Object.defineProperty

En Vue 2, cada propiedad reactiva se convertía en un par de getters y setters usando Object.defineProperty.

  • La limitación: Vue tenía que recorrer el objeto completo al inicializarlo. Si añadías una propiedad nueva o modificabas un índice de un array directamente (arr[0] = x), Vue no se enteraba. Por eso existían soluciones como Vue.set().

Vue 3: el poder de Proxy

Vue 3 cambió completamente el enfoque usando Proxies de JavaScript.

Un Proxy envuelve un objeto y puede interceptar prácticamente cualquier operación: leer, escribir, borrar o añadir propiedades.

  • La ventaja: no importa cuándo ni cómo cambie el objeto. Vue puede detectarlo. El resultado es una reactividad más profunda, más predecible y con mejor rendimiento.

Los dos pilares: ref() vs reactive()

Si usas la Composition API, esta duda aparece antes de que termines tu primer café.

Característicaref()reactive()
Tipo de datoPrimitivos y objetosSolo objetos y colecciones
Acceso en JS.valueAcceso directo
En <template>Auto-desempaquetadoAcceso directo
Uso idealEstados simples y aisladosEstados complejos o anidados

Regla mental rápida: si es una sola cosa, ref. Si es una estructura, reactive.

El ciclo interno: track y trigger

El motor de reactividad de Vue funciona con un sistema sorprendentemente elegante:

  1. Track: cuando una función lee una variable reactiva, Vue registra esa relación.
  2. Trigger: cuando el valor cambia, Vue notifica a todas las funciones que dependen de él.
  3. Update: el componente se vuelve a renderizar. El Virtual DOM se encarga de actualizar solo lo necesario.

Tú cambias datos. Vue decide qué tocar en el DOM. Separación de responsabilidades en su máxima expresión.

Consejos de rendimiento (nivel 2026)

Si tu aplicación empieza a crecer, estas decisiones importan más de lo que parece.

  • shallowRef y shallowReactive: útiles cuando trabajas con objetos grandes que no necesitan reactividad profunda.
  • Cuidado al desestructurar: hacer esto rompe la reactividad:
index.js
const { nombre } = estadoReactivo; // mal

La forma correcta es:

index.js
import { reactive, toRefs } from 'vue';
 
const estado = reactive({ nombre: 'Vue' });
const { nombre } = toRefs(estado);

Ejemplo práctico: el contador más honesto del mundo

<script setup>
import { ref } from 'vue';

const tazasDeCafe = ref(0);

const incrementar = () => {
  tazasDeCafe.value++;
};
</script>
 
<template>
  <button @click="incrementar">
    Tazas consumidas: {{ tazasDeCafe }}
  </button>
</template>
<script>
export default {
  data() {
    return {
      tazasDeCafe: 0,
    };
  },
  methods: {
    incrementar() {
      this.tazasDeCafe++;
    },
  },
};
</script>
 
<template>
  <button @click="incrementar">
    Tazas consumidas: {{ tazasDeCafe }}
  </button>
</template>

Cada clic actualiza el estado. Vue detecta el cambio, vuelve a renderizar lo necesario y tú no tocas el DOM en ningún momento. Eso es la reactividad bien entendida: menos código imperativo, menos errores mentales y una interfaz que hace exactamente lo que debería.