Sobes.tech
Middle

როგორ მუშაობს რეაქტივობა Vue.js-ში?

sobes.tech AI

პასუხი AI-სგან

Vue.js-ის რეაქტივობა დაფუძნებულია "наблюდებლის" (Observer) მოდელზე.

როდესაც Vue-ის ინстанცია იქმნება, ის გადადის data ობიექტის ყველა თვისებაზე და გარდაქმნის მათ გეტტერებს და სეტტერებს Object.defineProperty-ის გამოყენებით Vue 2-ში ან Proxy-ს Vue 3-ში:

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-ზე, ამ template-ის Watcher-ი დაემატება Dep-ს message-ისთვის
});