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
Proxysegí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$setaz ú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
});