Sobes.tech
Middle

Hoe werkt de reactiviteit in Vue.js?

sobes.tech AI

Antwoord van AI

Reactiviteit in Vue.js is gebaseerd op het "observer"-patroon.

Wanneer een Vue-instantie wordt gemaakt, doorloopt deze alle eigenschappen van het data-object en zet ze om in getters en setters met behulp van Object.defineProperty in Vue 2 of Proxy in Vue 3.

Vue 2:

  • Bij toegang tot een eigenschap (getter), volgt Vue welke component deze gebruikt.
  • Bij wijziging van een eigenschap (setter), informeert Vue alle componenten die deze observeerden, zodat ze worden bijgewerkt (hertekenen van de sjabloon).

Vue 3:

  • Gebruikt Proxy om alle operaties op het object te onderscheppen (toevoegen, verwijderen van eigenschappen, wijzigen van waarden, etc.), wat een meer volledige reactiviteit biedt in vergelijking met Vue 2.
  • Dankzij Proxy heeft de reactiviteit van Vue 3 geen beperkingen van Vue 2 (geen $set nodig om nieuwe eigenschappen toe te voegen).

Belangrijke componenten van reactiviteit:

  • Observer: Transformeert data-eigenschappen in getters/setters (Vue 2) of behandelt ze met Proxy (Vue 3).
  • Dep (Dependency): Object dat is gekoppeld aan elke reactieve eigenschap en de lijst van afhankelijke Watchers opslaat.
  • Watcher: Vertegenwoordigt een component, een berekende eigenschap of watchers die afhankelijk zijn van reactieve data. Wanneer de data verandert, wordt de Watcher geïnformeerd en voert de bijbehorende actie uit (bijvoorbeeld het opnieuw tekenen van het component).

Voorbeeld (Vue 2):

// Interne implementatie (vereenvoudigd)
function defineReactive(obj, key, val) {
  let dep = new Dep(); // Maak een Dep voor de eigenschap

  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter() {
      // Als er een globale Watcher bestaat (bij het renderen van het component)
      if (Dep.target) {
        dep.depend(); // Voeg de Watcher toe aan de afhankelijkheidslijst van Dep
      }
      return val;
    },
    set: function reactiveSetter(newVal) {
      if (newVal === val) return;
      val = newVal;
      dep.notify(); // Informeer alle afhankelijke Watchers
    }
  });
}

// Hoe het eruitziet in een component
new Vue({
  data: {
    message: 'Hello' // defineReactive wordt toegepast op message
  },
  template: '<div>{{ message }}</div>' // Bij toegang tot message wordt de Watcher van deze template toegevoegd aan Dep message
});