Efectos trackers triggers: cómo Vue vincula datos

Clase 12 de 37Curso de Reactividad con Vue.js 3

Resumen

Construye reactividad real con confianza: efectos, trackers y triggers trabajan juntos para vincular datos y presentación en un mini framework al estilo de Vue. Aquí verás cómo un mapa de dependencias, un proxy y funciones efecto sostienen un sistema reactivo claro y extensible.

¿Cómo se crean efectos y dependencias con un mapa de deps?

Para determinar cuándo ejecutar un efecto, se definen dependencias que observan cambios. Se crea un mapa de dependencias con this.deps = new Map() para asociar cada propiedad reactiva con su efecto. Un efecto es una función pequeña enfocada en actualizar la UI según la propiedad observada.

  • Usar this.deps como registro de dependencias y sus efectos.
  • Asociar cada propiedad (por ejemplo, message) con su efecto.
  • Mantener efectos como funciones puras que leen estado y renderizan.

¿Qué es un efecto y cómo usa ptext?

Un efecto consulta el HTML y actualiza nodos con ptext asociados a la propiedad observada. Cuando esa propiedad cambia, el efecto se ejecuta y actualiza el contenido.

// Creación del mapa y efecto por propiedad
this.deps = new Map(); // dependencias

const effect = (target, name) => {
  const nodes = document.querySelectorAll(`[ptext="${name}"]`);
  nodes.forEach(node => {
    node.textContent = `${target[name]}`; // template string
  });
};

// Al registrar por primera vez una propiedad:
if (!this.deps.has(name)) {
  this.deps.set(name, () => effect(target, name));
}

¿Cómo operan trackers y triggers en el proxy?

La clave está en el proxy: el getter detecta accesos y hace el seguimiento con track, mientras que el setter detecta escrituras y dispara el trigger que ejecuta el efecto guardado. Así, datos y presentación quedan vinculados.

  • track(target, name): registra la dependencia al acceder la propiedad.
  • trigger(name): ejecuta el efecto de la propiedad al modificarse.
  • Uso de self = this para invocar métodos desde las trampas del proxy.

¿Dónde se invoca track en el getter?

En el acceso a cualquier propiedad reactiva se llama a track. Esto asegura que la dependencia quede registrada en el mapa y tenga su efecto listo.

const self = this;
this.state = new Proxy(this.data, {
  get(target, name) {
    self.track(target, name); // seguimiento de dependencia
    return target[name];
  },
  set(target, name, value) {
    target[name] = value;
    self.trigger(name); // ejecutar efecto
    return true;
  }
});

¿Cómo registra track la primera vez?

Cuando no existe la dependencia en el mapa, track crea y guarda el efecto para esa propiedad. La próxima vez, ya estará disponible para ejecutarse al cambiar el valor.

track(target, name) {
  if (!this.deps.has(name)) {
    const effect = () => {
      const nodes = document.querySelectorAll(`[ptext="${name}"]`);
      nodes.forEach(node => { node.textContent = `${target[name]}`; });
    };
    this.deps.set(name, effect);
  }
}

¿Cuándo se dispara trigger en el setter?

Al escribir una propiedad, el setter llama a trigger con el nombre de la dependencia. Como los efectos son funciones, basta con ejecutarlos.

trigger(name) {
  const effect = this.deps.get(name);
  if (effect) effect(); // ejecuta el efecto anidado
}

¿Qué retos prácticos refuerzan pmodel y pbinds?

Se propone extender la reactividad para cubrir nuevos casos y solidificar el entendimiento del patrón.

  • Agregar efecto para pmodel: cuando cambie una propiedad reactiva, el efecto debe reevaluar el value de los inputs con pmodel igual a esa propiedad.
  • Crear directiva pbinds: vincular un atributo de HTML (por ejemplo, el source de un image) a una propiedad reactiva. Si la propiedad cambia, el atributo se actualiza.

¿Cómo pensar el efecto de pmodel?

  • Seleccionar inputs con pmodel que apunten a la propiedad.
  • Establecer input.value desde el estado reactivo.
  • Reutilizar el mapa de dependencias para ejecutar el efecto cuando cambie la propiedad.
// Esqueleto de efecto para pmodel
const pmodelEffect = (target, name) => {
  const inputs = document.querySelectorAll(`[pmodel="${name}"]`);
  inputs.forEach(i => { i.value = `${target[name]}`; });
};

¿Cómo abordar pbinds para atributos dinámicos?

  • Interpretar un selector que indique el atributo objetivo y la propiedad reactiva.
  • Actualizar el atributo con el valor actual del estado.
  • Reusar track y trigger para mantener la sincronización.
// Esqueleto general para pbinds (atributo <- propiedad)
const pbindsEffect = (target, attr, prop) => {
  const nodes = document.querySelectorAll(`[pbinds]`);
  nodes.forEach(el => {
    // asume que puedes obtener attr y prop desde el selector de la directiva
    el.setAttribute(attr, `${target[prop]}`);
  });
};

Habilidades y conceptos que consolidas: identificación de dependencias reactivas, diseño de efectos focalizados, uso de trackers y triggers con getter/setter en proxy, manejo de Map para un mapa de dependencias, y creación de directivas como ptext, pmodel y pbinds para vincular datos con la presentación. Todo ello te prepara para comprender mejor cómo Vue opera internamente y aplicarlo con soltura.

¿Quieres comentar cómo extendiste pmodel o pbinds y qué decisiones tomaste en tu mini framework?