JavaScript reaktivligining eng yaxshi izohi

Ko'pgina oldingi JavaScript ramkalari (Masalan: Angular, React va Vue) o'zlarining Reaktivlik dvigatellariga ega. Reaktivlik nima ekanligini va u qanday ishlashini tushunib, siz o'zingizning rivojlanish mahoratingizni oshirib, JavaScript ramkalaridan yanada samarali foydalanishingiz mumkin. Quyidagi video va maqolada biz Vue manba kodida ko'rgan reaktivlik turini yaratamiz.

Agar siz ushbu videoni maqolani o'qish o'rniga tomosha qilsangiz, Vue-ning yaratuvchisi Evan You bilan reaktivlik va ishonchli vakillarni muhokama qiladigan seriyadagi navbatdagi videoni tomosha qiling.

Reaktivlik tizimi

Vue-ning reaktivlik tizimi sehrga o'xshashi mumkin, agar siz uni birinchi marta ishlayotgan bo'lsangiz. Ushbu oddiy Vue ilovasini oling:

Qandaydir bir tarzda Vue, agar narx o'zgarsa, u uchta narsani qilishi kerakligini biladi:

  • Veb-saytimizdagi narxlarni yangilang.
  • Narx * miqdorini ko'paytiradigan iborani qayta hisoblang va sahifani yangilang.
  • TotalPriceWithTax funktsiyasini yana chaqiring va sahifani yangilang.

Ammo kuting, men hayron bo'lganingizni eshitaman, Vue narx o'zgarganda nimani yangilashni biladi va u hamma narsani qanday qilib kuzatib boradi?

Odatda JavaScript dasturlash kabi ishlamaydi

Agar sizga tushunarli bo'lmasa, biz hal qilishimiz kerak bo'lgan katta muammo shundaki, dasturlash odatda ishlamaydi. Masalan, agar men ushbu kodni ishlatsam:

Sizningcha, nima chop etadi? Vue-dan foydalanmayotganimiz sababli, u 10-ni chop etadi.

Vue-da biz narxlar yoki miqdorlar har doim yangilanib turishini istaymiz. Biz xohlaymiz:

Afsuski, JavaScript protsessual, reaktiv emas, shuning uchun bu haqiqiy hayotda ishlamaydi. Umumiy reaktivlik qilish uchun biz JavaScript-dan foydalanib, o'zimizni boshqacha tutishimiz kerak.

Muammo

Biz hisob-kitobni qanday hisoblashimiz kerakligini tejashimiz kerak, shunda narx yoki miqdor o'zgarganda uni qayta ishga tushirishimiz mumkin.

Qaror

Birinchidan, biz dasturimizga "Men ishlamoqchi bo'lgan kodni saqlayman, boshqa vaqtda ishga tushirishingiz kerak bo'lishi mumkin." Keyin biz kodni ishlatishni xohlaymiz va agar narx bo'lsa yoki miqdor o'zgaruvchilari yangilanadi, saqlangan kodni qayta ishga tushiring.

Buni biz yana ishga tushirishimiz uchun funktsiyani yozib olish orqali amalga oshirishimiz mumkin.

E'tibor bering, biz noma'lum funktsiyani maqsad o'zgaruvchisi ichida saqlaymiz va keyin yozuv funktsiyasini chaqiramiz. ES6 o'q sintaksisidan foydalanib, men buni quyidagicha yozishim mumkin edi:

Yozuvning ta'rifi shunchaki:

Biz maqsadni (bizning holimizda {total = price * miqdor}) saqlamoqdamiz, shunda uni keyinroq bajarishimiz mumkin, ehtimol biz barcha yozgan narsalarimizni takrorlash funktsiyasi yordamida.

Bu biz saqlash qatorida saqlagan barcha anonim funktsiyalardan o'tadi va ularning har birini bajaradi.

Keyin bizning kodimizda quyidagilar bo'lishi mumkin:

Etarlicha sodda, to'g'rimi? Bu kodni to'liq o'qib chiqing, agar uni yana o'qib chiqishga harakat qilsangiz. FYI, men buni biron bir usulda kodlayapman, agar nima uchun siz buni bilmoqchi bo'lsangiz.

Muammo

Agar kerak bo'lsa, biz maqsadlarni yozib olishni davom ettirishimiz mumkin, ammo bizning ilovamizda kengroq echim topilsa yaxshi bo'lardi. Ehtimol, biz ularni qayta ishga tushirishimiz kerak bo'lganda, ular haqida xabardor qilinadigan maqsadlar ro'yxatini saqlash haqida g'amxo'rlik qiladigan sinf.

Qaror: Bog'lanish klassi

Ushbu muammoni hal qilishni boshlashning usullaridan biri bu xatti-harakatni o'zining sinfiga, standart dasturlash kuzatuvchisi modelini amalga oshiradigan qaramlik sinfiga kiritishdir.

Shunday qilib, agar biz o'z qaramligimizni boshqarish uchun JavaScript sinfini yaratsak (bu Vue narsalarga qanday qarashga yaqinroq bo'lsa), u quyidagicha ko'rinishi mumkin:

Saqlash o'rniga, biz hozirda anonim funktsiyalarimizni abonentlarda saqlayotganimizga e'tibor bering. Bizning yozuv funktsiyamizning o'rniga biz hozir qo'ng'iroq qilamiz va endi takrorlash o'rniga bildirishnomadan foydalanamiz. Buni ishga tushirish uchun:

U hali ham ishlaydi va endi bizning kodimiz qayta ishlatiladigan bo'lib tuyuladi. Faqatgina g'alati his qiladigan narsa bu maqsadni belgilash va ishlatishdir.

Muammo

Kelgusida biz har bir o'zgaruvchi uchun Dep sinfiga ega bo'lamiz va yangilanishlarni kuzatib borish kerak bo'lgan noma'lum funktsiyalarni yaratish xususiyatlarini yaxshilab ko'rib chiqamiz. Ehtimol, bu xatti-harakatlarga g'amxo'rlik qilish uchun kuzatuvchi funktsiyasi bo'lishi mumkin.

Shunday qilib, qo'ng'iroq qilish o'rniga:

(bu faqat yuqoridagi kod)

Buning o'rniga biz faqat qo'ng'iroq qilishimiz mumkin:

Qaror: Qo'riqchi vazifasi

Watcher funktsiyamizda bir nechta oddiy narsalarni bajarishimiz mumkin:

Ko'rinib turibdiki, kuzatuvchi funktsiyasi myFunc argumentini oladi, global maqsadli mulkimiz sifatida maqsadimizni obuna sifatida qo'shish uchun dep.depend () ni chaqiradi, maqsad vazifasini chaqiradi va maqsadni qayta o'rnatadi.

Endi biz quyidagilarni ishga tushirganimizda:

Siz nega biz maqsadni global o'zgaruvchi sifatida amalga oshirganimizdan, kerak bo'lganda o'z funktsiyalarimizga o'tkazmasligimiz bilan qiziqasiz. Buning yaxshi sababi bor va bu bizning maqolamiz oxirida aniq bo'ladi.

Muammo

Bizda bitta Dep sinf bor, lekin biz istagan har bir o'zgaruvchi o'z Depiga ega bo'lishini xohlaymiz. Boshqa narsalarga o'tmasdan oldin narsalarni mulkka o'tkazishga ijozat bering

Bir daqiqaga faraz qilaylik, har bir mulkimiz (narx va miqdor) o'z ichki Dep sinfiga ega.

Endi biz yugurganimizda:

Ma'lumotlar.price qiymatiga kirish imkoniyati mavjud bo'lganligi sababli (u), ushbu xususiyatning "klassi" anonim funktsiyamizni (maqsadda saqlangan) o'z obunachilar qatoriga (dep.depend () qo'ng'iroq qilib) yo'naltirishini xohlayman. Ma'lumotlar to'plamiga kirish imkoniyati mavjud bo'lganligi sababli, men Dep sinfiga tegishli bo'lgan ushbu noma'lum funktsiyani (maqsadda saqlangan) o'z obunachilar qatoriga o'tkazishini istayman.

Agarda menda faqat data.price kirish mumkin bo'lgan boshqa anonim funksiya bo'lsa, men buni Dep sinf narxiga o'tkazish istayman.

Men qachon dep.notify () narxining obunachilariga qo'ng'iroq qilishni xohlayman? Men ularni narx belgilanganda chaqirilishini istayman. Maqolaning oxiriga kelib men konsolga kirib, quyidagilarni bajarishni istayman.

Ma'lumot xususiyatiga (narx yoki miqdor kabi) bog'lanishning biron bir usuli kerak, shuning uchun kirish paytida biz maqsadni obunachilar qatorida saqlashimiz mumkin va u o'zgartirilganida, bizning obunachilarimiz qatorida saqlanadigan funktsiyalar ishga tushadi.

Qaror: Object.defineProperty ()

Biz aniq ES5 JavaScript-ga ega bo'lgan Object.defineProperty () funktsiyasi haqida o'rganishimiz kerak. Bu bizga mulk uchun topuvchi va ajratuvchi funktsiyalarni aniqlash imkonini beradi. Lemme sizga asosiy sinfdan foydalanishni ko'rsatib beradi, men buni Dep sinfimiz bilan qanday ishlatishni ko'rsatmasimdan oldin.

Ko'rib turganingizdek, u faqat ikkita chiziqni qayd etadi. Biroq, u aslida biron bir qiymatga ega bo'lmaydi yoki o'rnatmaydi, chunki biz funktsiyani haddan tashqari oshirib yubordik. Keling, uni yana qo'shamiz. get () qiymati qaytarilishini kutadi va () hali ham qiymatni yangilashi kerak, shuning uchun hozirgi narx qiymatimizni saqlash uchun ichki qiymatni o'zgartiruvchi qo'shaylik.

Endi bizning to'plamimiz to'g'ri ishlayapti deb o'ylaysiz, konsolga nima yoziladi?

Shunday qilib, biz qadriyatlarni olgandan va o'rnatganimizdan xabardor bo'lishning bir usuli bor. Bir muncha rekursiya bilan biz buni ma'lumotlar qatoridagi barcha elementlar uchun ishlatamiz, to'g'rimi?

FYI, Object.keys (ma'lumotlar) ob'ekt tugmalarining qatorini qaytaradi.

Endi har bir narsa pichirlash va o'rnatuvchilarga ega va biz buni konsolda ko'rmoqdamiz.

Both Ikkala fikrni ham birlashtirish

Shunga o'xshash kod bo'limi ishga tushganda va narxning qiymatini olganda, biz ushbu anonim funktsiyani (maqsad) eslab qolishlarini xohlaymiz. Agar narx o'zgarsa yoki yangi qiymatga ega bo'lsa, u qayta ishga tushirish uchun ushbu funktsiyani ishga tushiradi, chunki bu chiziq unga bog'liqligini biladi. Shunday qilib, siz bu haqda o'ylashingiz mumkin.

Get => Ushbu anonim funktsiyani eslab qoling, qiymatimiz o'zgarganda biz uni yana ishga tushiramiz.

Set => Saqlangan noma'lum funktsiyani ishga tushiring, bizning qiymatimiz endi o'zgargan.

Yoki Dep sinfimiz misolida

Joriy maqsadni saqlab qolish uchun narxga kirish (olish) => qo'ng'irog'iga bog'liq ()

Narxlar to'plami => qo'ng'iroq dep.notify () narx bo'yicha, barcha maqsadlarni qayta bajaring

Keling, ushbu ikkita fikrni birlashtirib, oxirgi kodimizni ko'rib chiqaylik.

Va endi biz atrofida o'ynayotganda konsolimizda nima bo'lishiga qarang.

Aynan biz nimani orzu qilsak edi! Ham narx, ham miqdor haqiqatan ham reaktivdir! Bizning umumiy kodimiz narx yoki miqdor qiymati o'zgarganda yangilanadi.

Vue hujjatlaridagi ushbu rasm endi mantiqiy bo'lishi kerak.

Siz chiroyli va binafsharang ma'lumot uzatgichlarni va to'sarlarni ko'rasizmi? Bu tanish ko'rinishi kerak! Har bir komponentli misolda kuzatuvchiga (ko'k rangda) ega, u kirish joyidan (qizil chiziq) bog'liqlikni yig'adi. Keyinchalik sozlagich chaqirilganda, u tarkibiy qismni qayta ko'rsatishga olib keladigan tomoshabinni xabardor qiladi. Mana yana bir nechta o'z izohlarim bilan rasm.

Ha, endi bu ko'proq ma'noga ega emasmi?

Shubhasiz, Vue-ni qopqoq ostida qanday qilish murakkabroq, ammo endi siz asoslarini bilasiz.

Xo'sh, biz nimani bilib oldik?

  • Qanday qaramlik toifalarini (qaram) to'playdigan va barcha qaramliklarni qayta ishlaydigan Dep sinfini qanday yaratish kerak (xabar bering).
  • Bog'lanish sifatida qo'shilishi kerak bo'lgan (maqsad) kerak bo'lishi mumkin bo'lgan biz ishlayotgan kodni boshqarish uchun qanday qilib kuzatuvchini yaratish kerak.
  • Getters va setters-ni yaratish uchun Object.defineProperty () -dan qanday foydalanish kerak.

Keyingi nima?

Agar siz men bilan ushbu maqolada tanishishni yoqtirsangiz, o'rganish yo'lingizdagi navbatdagi qadam - ishonchli shaxslar bilan reaktivlik haqida ma'lumot olish. VueMastery.com saytida mening bepul videomni aniq ko'rib chiqing, u erda men Vue.js yaratuvchisi Evan You bilan suhbatlashaman.

Dastlab www.vuemastery.com da nashr etilgan.