Sobes.tech
Middle

Vue.js-деги реактивтүүлүк кантип иштейт?

sobes.tech AI

AIден жооп

Vue.jsтин реактивдүүлүк негизделген "наблюдатель" (Observer) үлгүсүнө.

Vue үлгүсү түзүлгөндө, ал data объектиндеги бардык мүнөздөмөлөр аркылуу өтүп, аларды Object.defineProperty аркылуу Vue 2дө геттерлер жана сеттерлерге айлантат же Vue 3дө Proxy колдонулат.

Vue 2:

  • Мүнөздөмөгө (геттер) киргенде, Vue кайсы компонент аны колдонуп жатканын көзөмөлдөйт.
  • Мүнөздөмө өзгөргөндө (сеттер), Vue аны көзөмөлдөп жаткан бардык компоненттерге жаңыртуу керектигин билдирет (шаңырак кайра чийүү).

Vue 3:

  • Бардык операцияларды (кошуу, өчүрүү, маанини өзгөртүү ж.б.) кармай турган Proxy колдонуп, Vue 2ге караганда көбүрөөк реактивдүүлүк камсыз кылат.
  • Proxy аркылуу Vue 3дүн реактивдүүлүгү Vue 2нин чектөөлөрүнөн ажыратылган (жаңы мүнөздөмөлөрдү кошуу үчүн $set талап кылынбайт).

Реактивдүүлүктүн негизги компоненттери:

  • Observer: Дата мүнөздөмөлөрүн геттерлер жана сеттерлерге айлантат (Vue 2), же Proxy аркылуу иштетет (Vue 3).
  • Dep (Dependency): Ар бир реактивдүү мүнөздөмө менен байланышкан объект, ал көз каранды Watcher-лердин тизмесин сактайт.
  • Watcher: Компонент, эсептелүүчү мүнөздөмө же көзөмөлчүлөр, алар реактивдүү маалыматтарга көз каранды. Маалыматтар өзгөргөндө, Watcher кабардар болуп, тиешелүү аракетти баштайт (мисалы, компонентти кайра чийүү).

Мисал (Vue 2):

// Ички ишке ашыруу (жөнөкөйлөштүрүлгөн)
function defineReactive(obj, key, val) {
  let dep = new Dep(); // Мүнөздөмө үчүн Dep түзөбүз

  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter() {
      // Эгер глобалдык Watcher бар болсо (компонент чийилип жатканда)
      if (Dep.target) {
        dep.depend(); // Watcher-ди Depтин көзкарандылыктар тизмесине кошуу
      }
      return val;
    },
    set: function reactiveSetter(newVal) {
      if (newVal === val) return;
      val = newVal;
      dep.notify(); // Бардык көзкаранды Watcher-лерге кабар берүү
    }
  });
}

// Бул компонентте кандай көрүнөт
new Vue({
  data: {
    message: 'Hello' // defineReactive message үчүн колдонулат
  },
  template: '<div>{{ message }}</div>' // messageке киргенде, бул шаблондун Watcher-и Depке кошулат
});