Sobes.tech
Middle

Hogyan működik a reaktivitás a Vue.js-ben?

sobes.tech MI

Válasz az MI-től

A Vue.js reaktivitása az "figyelő" (Observer) mintán alapul.

Amikor egy Vue példányt hozunk létre, az végigmegy az összes data objektum tulajdonságán, és getterek és setterek segítségével alakítja át azokat, a Vue 2-ben Object.defineProperty-t, a Vue 3-ban pedig Proxy-t használva.

Vue 2:

  • Amikor egy tulajdonsághoz (getter) hozzáférünk, Vue nyomon követi, melyik komponens használja azt.
  • Amikor egy tulajdonságot módosítunk (setter), Vue értesíti az összes olyan komponenst, amely figyelte azt, hogy frissítse magát (újrarajzolás).

Vue 3:

  • A Proxy segítségével minden műveletet (tulajdonság hozzáadása, törlése, érték módosítása stb.) elfog, így biztosítva a teljesebb reaktivitást a Vue 2-höz képest.
  • A Proxy-nak köszönhetően a Vue 3 reaktivitása nem korlátozott a Vue 2-hez képest (nem szükséges $set az új tulajdonságok hozzáadásához).

A reaktivitás kulcsfontosságú komponensei:

  • Observer: Átalakítja az adat tulajdonságait getterek és setterek segítségével (Vue 2), vagy Proxy-val kezeli azokat (Vue 3).
  • Dep (Dependencia): Minden reaktív tulajdonsághoz társított objektum, amely tárolja az attól függő Watcher-ek listáját.
  • Watcher: Egy komponens, számított tulajdonság vagy figyelő, amely a reaktív adatoktól függ. Amikor az adatok változnak, a Watcher értesül és végrehajtja a megfelelő műveletet (pl. a komponens újrarajzolása).

Példa (Vue 2):

// Egyszerűsített belső implementáció
function defineReactive(obj, key, val) {
  let dep = new Dep(); // Dep létrehozása a tulajdonsághoz

  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter() {
      // Ha van globális Watcher (a komponens renderelésekor)
      if (Dep.target) {
        dep.depend(); // A Watcher hozzáadása a Dep függőségi listájához
      }
      return val;
    },
    set: function reactiveSetter(newVal) {
      if (newVal === val) return;
      val = newVal;
      dep.notify(); // Minden függő Watcher értesítése
    }
  });
}

// Hogyan néz ki egy komponensben
new Vue({
  data: {
    message: 'Hello' // defineReactive alkalmazva lesz a message-re
  },
  template: '<div>{{ message }}</div>' // A message elérésénél a template Watcher-je hozzáadódik a Dep message-hez
});