Veb-komponentlar hayot sikliga chuqur sho'ng'ish: maxsus element yaratish, ulanish, atribut o'zgarishlari va uzilishni o'rganish. Zamonaviy veb-ilovalar uchun mustahkam va qayta ishlatiladigan komponentlar yarating.
Veb-komponentlarning hayot sikli: Maxsus elementlarni yaratish va boshqarishni o'zlashtirish
Veb-komponentlar zamonaviy veb-dasturlashda qayta ishlatiladigan va inkapsulyatsiya qilingan UI elementlarini yaratish uchun kuchli vositadir. Veb-komponentning hayot siklini tushunish mustahkam, texnik xizmat ko'rsatish oson va samarali ilovalarni yaratish uchun juda muhimdir. Ushbu keng qamrovli qo'llanma veb-komponent hayot siklining turli bosqichlarini o'rganadi, maxsus elementlarni yaratish va boshqarishni o'zlashtirishingizga yordam beradigan batafsil tushuntirishlar va amaliy misollarni taqdim etadi.
Veb-komponentlar nima?
Veb-komponentlar - bu inkapsulyatsiya qilingan uslub va xulq-atvorga ega bo'lgan qayta ishlatiladigan maxsus HTML elementlarini yaratishga imkon beruvchi veb-platforma API'lari to'plamidir. Ular uchta asosiy texnologiyadan iborat:
- Maxsus elementlar: O'zingizning HTML teglaringizni va ularga bog'liq JavaScript mantig'ini aniqlashga imkon beradi.
- Soya DOM (Shadow DOM): Komponent uchun alohida DOM daraxtini yaratib, uni global hujjat uslublari va skriptlaridan himoya qilib, inkapsulyatsiyani ta'minlaydi.
- HTML shablonlari: Samarali klonlanishi va DOMga kiritilishi mumkin bo'lgan qayta ishlatiladigan HTML qismlarini aniqlashga imkon beradi.
Veb-komponentlar kodni qayta ishlatish imkoniyatini oshiradi, texnik xizmat ko'rsatishni yaxshilaydi va murakkab foydalanuvchi interfeyslarini modulli va tartibli tarzda qurishga imkon beradi. Ular barcha asosiy brauzerlar tomonidan qo'llab-quvvatlanadi va har qanday JavaScript freymvorki yoki kutubxonasi bilan yoki hatto hech qanday freymvorksiz ham ishlatilishi mumkin.
Veb-komponentlarning hayot sikli
Veb-komponentlarning hayot sikli maxsus elementning yaratilishidan tortib DOMdan olib tashlanishigacha bo'lgan turli bosqichlarini belgilaydi. Ushbu bosqichlarni tushunish sizga to'g'ri vaqtda aniq harakatlarni bajarishga imkon beradi, bu esa komponentingizning to'g'ri va samarali ishlashini ta'minlaydi.
Asosiy hayot sikli metodlari:
- constructor(): Element yaratilganda yoki yangilanganda konstruktor chaqiriladi. Bu yerda siz komponent holatini ishga tushirasiz va uning soya DOMini (agar kerak bo'lsa) yaratasiz.
- connectedCallback(): Maxsus element hujjatning DOMiga har safar ulanganda chaqiriladi. Bu ma'lumotlarni olish, hodisalarni tinglovchilarni qo'shish yoki komponentning dastlabki tarkibini render qilish kabi sozlash vazifalarini bajarish uchun yaxshi joy.
- disconnectedCallback(): Maxsus element hujjatning DOMidan har safar uzilganda chaqiriladi. Bu yerda xotira sizib chiqishining oldini olish uchun hodisalarni tinglovchilarni olib tashlash yoki taymerlarni bekor qilish kabi resurslarni tozalashingiz kerak.
- attributeChangedCallback(name, oldValue, newValue): Maxsus element atributlaridan biri har safar qo'shilganda, olib tashlanganda, yangilanganda yoki almashtirilganda chaqiriladi. Bu sizga komponent atributlaridagi o'zgarishlarga javob berish va uning xulq-atvorini shunga mos ravishda yangilash imkonini beradi. Siz
observedAttributes
statik getteri yordamida qaysi atributlarni kuzatishni xohlayotganingizni ko'rsatishingiz kerak. - adoptedCallback(): Maxsus element har safar yangi hujjatga ko'chirilganda chaqiriladi. Bu iframelar bilan ishlaganda yoki elementlarni ilovaning turli qismlari o'rtasida ko'chirishda dolzarbdir.
Har bir hayot sikli metodini chuqurroq o'rganish
1. constructor()
Konstruktor sizning maxsus elementingizning yangi nusxasi yaratilganda chaqiriladigan birinchi metoddir. Bu quyidagilar uchun ideal joy:
- Komponentning ichki holatini ishga tushirish.
this.attachShadow({ mode: 'open' })
yokithis.attachShadow({ mode: 'closed' })
yordamida Soya DOM yaratish.mode
Soya DOMga komponentdan tashqaridagi JavaScriptdan kirish mumkinligini (open
) yoki yo'qligini (closed
) belgilaydi. Odatda osonroq diskretlash (debugging) uchunopen
dan foydalanish tavsiya etiladi.- Hodisalarni qayta ishlovchi metodlarni komponent nusxasiga bog'lash (
this.methodName = this.methodName.bind(this)
yordamida), buthis
ning qayta ishlovchi ichida komponent nusxasiga ishora qilishini ta'minlash uchun.
Konstruktor uchun muhim mulohazalar:
- Siz konstruktorda hech qanday DOM manipulyatsiyasini amalga oshirmasligingiz kerak. Element hali DOMga to'liq ulanmagan va uni o'zgartirishga urinish kutilmagan xatti-harakatlarga olib kelishi mumkin. DOM manipulyatsiyasi uchun
connectedCallback
dan foydalaning. - Konstruktorda atributlardan foydalanishdan saqlaning. Atributlar hali mavjud bo'lmasligi mumkin. Buning o'rniga
connectedCallback
yokiattributeChangedCallback
dan foydalaning. - Avval
super()
ni chaqiring. Agar siz boshqa sinfdan (odatdaHTMLElement
) meros olsangiz, bu majburiydir.
Misol:
class MyCustomElement extends HTMLElement {
constructor() {
super();
// Soya ildizini yaratish
this.shadow = this.attachShadow({mode: 'open'});
this.message = "Salom, dunyo!";
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
alert(this.message);
}
}
2. connectedCallback()
connectedCallback
maxsus element hujjatning DOMiga ulanganda chaqiriladi. Bu quyidagilar uchun asosiy joy:
- API'dan ma'lumotlarni olish.
- Komponentga yoki uning Soya DOMiga hodisalarni tinglovchilarni qo'shish.
- Komponentning dastlabki tarkibini Soya DOMga render qilish.
- Agar konstruktorda darhol kuzatish imkoni bo'lmasa, atribut o'zgarishlarini kuzatish.
Misol:
class MyCustomElement extends HTMLElement {
// ... konstruktor ...
connectedCallback() {
// Tugma elementini yaratish
const button = document.createElement('button');
button.textContent = 'Meni bosing!';
button.addEventListener('click', this.handleClick);
this.shadow.appendChild(button);
// Ma'lumotlarni olish (misol)
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
this.data = data;
this.render(); // UI'ni yangilash uchun render metodini chaqirish
});
}
render() {
// Ma'lumotlarga asoslanib Soya DOMni yangilash
const dataElement = document.createElement('p');
dataElement.textContent = JSON.stringify(this.data);
this.shadow.appendChild(dataElement);
}
handleClick() {
alert("Tugma bosildi!");
}
}
3. disconnectedCallback()
disconnectedCallback
maxsus element hujjatning DOMidan uzilganda chaqiriladi. Bu quyidagilar uchun juda muhim:
- Xotira sizib chiqishining oldini olish uchun hodisalarni tinglovchilarni olib tashlash.
- Har qanday taymerlar yoki intervallarni bekor qilish.
- Komponent ushlab turgan har qanday resurslarni bo'shatish.
Misol:
class MyCustomElement extends HTMLElement {
// ... konstruktor, connectedCallback ...
disconnectedCallback() {
// Hodisa tinglovchisini olib tashlash
this.shadow.querySelector('button').removeEventListener('click', this.handleClick);
// Har qanday taymerlarni bekor qilish (misol)
if (this.timer) {
clearInterval(this.timer);
}
console.log('Komponent DOMdan uzildi.');
}
}
4. attributeChangedCallback(name, oldValue, newValue)
attributeChangedCallback
maxsus elementning atributi har o'zgarganda chaqiriladi, lekin faqat observedAttributes
statik getterida ro'yxatga olingan atributlar uchun. Bu metod quyidagilar uchun zarur:
- Atribut qiymatlaridagi o'zgarishlarga reaksiya bildirish va komponentning xulq-atvori yoki ko'rinishini yangilash.
- Atribut qiymatlarini tekshirish (validatsiya qilish).
Asosiy jihatlar:
- Siz kuzatmoqchi bo'lgan atribut nomlari massivini qaytaradigan
observedAttributes
nomli statik getterni aniqlashingiz shart. attributeChangedCallback
faqatobservedAttributes
da ro'yxatga olingan atributlar uchun chaqiriladi.- Metod uchta argument qabul qiladi: o'zgargan atributning
name
(nomi),oldValue
(eski qiymati) vanewValue
(yangi qiymati). - Agar atribut yangi qo'shilgan bo'lsa,
oldValue
null
bo'ladi.
Misol:
class MyCustomElement extends HTMLElement {
// ... konstruktor, connectedCallback, disconnectedCallback ...
static get observedAttributes() {
return ['message', 'data-count']; // 'message' va 'data-count' atributlarini kuzatish
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'message') {
this.message = newValue; // Ichki holatni yangilash
this.renderMessage(); // Xabarni qayta render qilish
} else if (name === 'data-count') {
const count = parseInt(newValue, 10);
if (!isNaN(count)) {
this.count = count; // Ichki hisobni yangilash
this.renderCount(); // Hisobni qayta render qilish
} else {
console.error('Noto‘g‘ri data-count atribut qiymati:', newValue);
}
}
}
renderMessage() {
// Soya DOMda xabar ko'rinishini yangilash
let messageElement = this.shadow.querySelector('.message');
if (!messageElement) {
messageElement = document.createElement('p');
messageElement.classList.add('message');
this.shadow.appendChild(messageElement);
}
messageElement.textContent = this.message;
}
renderCount(){
let countElement = this.shadow.querySelector('.count');
if(!countElement){
countElement = document.createElement('p');
countElement.classList.add('count');
this.shadow.appendChild(countElement);
}
countElement.textContent = `Hisob: ${this.count}`;
}
}
attributeChangedCallback'dan samarali foydalanish:
- Kiritishni tekshirish: Ma'lumotlar yaxlitligini ta'minlash uchun yangi qiymatni tekshirish uchun ushbu qayta chaqiruvdan foydalaning.
- Yangilanishlarni kechiktirish (Debounce): Hisoblash uchun qimmat yangilanishlar uchun, ortiqcha qayta render qilishni oldini olish maqsadida atribut o'zgarishlarini qayta ishlovchisini kechiktirishni (debouncing) ko'rib chiqing.
- Alternativalarni ko'rib chiqish: Murakkab ma'lumotlar uchun atributlar o'rniga xususiyatlardan foydalanishni va o'zgarishlarni to'g'ridan-to'g'ri xususiyat setterida qayta ishlashni ko'rib chiqing.
5. adoptedCallback()
adoptedCallback
maxsus element yangi hujjatga ko'chirilganda (masalan, bir iframedan boshqasiga ko'chirilganda) chaqiriladi. Bu kamroq qo'llaniladigan hayot sikli metodi, ammo hujjat kontekstlari bilan bog'liq murakkabroq stsenariylar bilan ishlaganda undan xabardor bo'lish muhimdir.
Misol:
class MyCustomElement extends HTMLElement {
// ... konstruktor, connectedCallback, disconnectedCallback, attributeChangedCallback ...
adoptedCallback() {
console.log('Komponent yangi hujjatga qabul qilindi.');
// Komponent yangi hujjatga ko'chirilganda kerakli sozlashlarni bajaring
// Bu tashqi resurslarga havolalarni yangilash yoki ulanishlarni qayta tiklashni o'z ichiga olishi mumkin.
}
}
Maxsus elementni aniqlash
Maxsus element sinfingizni aniqlaganingizdan so'ng, uni customElements.define()
yordamida brauzerda ro'yxatdan o'tkazishingiz kerak:
customElements.define('my-custom-element', MyCustomElement);
Birinchi argument sizning maxsus elementingiz uchun teg nomi (masalan, 'my-custom-element'
). Teg nomi standart HTML elementlari bilan ziddiyatlarning oldini olish uchun albatta chiziqcha (-
) o'z ichiga olishi kerak.
Ikkinchi argument sizning maxsus elementingiz xulq-atvorini belgilaydigan sinf (masalan, MyCustomElement
).
Maxsus elementni aniqlaganingizdan so'ng, uni HTML'ingizda boshqa har qanday HTML elementi kabi ishlatishingiz mumkin:
<my-custom-element message="Atributdan salom!" data-count="10"></my-custom-element>
Veb-komponentlar hayot siklini boshqarish bo'yicha eng yaxshi amaliyotlar
- Konstruktorni yengil saqlang: Konstruktorda DOM manipulyatsiyasi yoki murakkab hisob-kitoblarni bajarishdan saqlaning. Bu vazifalar uchun
connectedCallback
dan foydalaning. - Resurslarni
disconnectedCallback
da tozalang: Xotira sizib chiqishining oldini olish uchun har doim hodisalarni tinglovchilarni olib tashlang, taymerlarni bekor qiling va resurslarnidisconnectedCallback
da bo'shating. observedAttributes
dan oqilona foydalaning: Faqatgina reaksiya bildirish kerak bo'lgan atributlarni kuzating. Keraksiz atributlarni kuzatish unumdorlikka ta'sir qilishi mumkin.- Renderlash kutubxonasidan foydalanishni ko'rib chiqing: Murakkab UI yangilanishlari uchun jarayonni soddalashtirish va unumdorlikni oshirish uchun LitElement yoki uhtml kabi renderlash kutubxonasidan foydalanishni ko'rib chiqing.
- Komponentlaringizni sinchkovlik bilan sinab ko'ring: Komponentlaringizning hayot sikli davomida to'g'ri ishlashini ta'minlash uchun birlik testlarini yozing.
Misol: Oddiy hisoblagich komponenti
Keling, veb-komponent hayot siklidan foydalanishni namoyish etadigan oddiy hisoblagich komponentini yaratamiz:
class CounterComponent extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
this.count = 0;
this.increment = this.increment.bind(this);
}
connectedCallback() {
this.render();
this.shadow.querySelector('button').addEventListener('click', this.increment);
}
disconnectedCallback() {
this.shadow.querySelector('button').removeEventListener('click', this.increment);
}
increment() {
this.count++;
this.render();
}
render() {
this.shadow.innerHTML = `
<p>Hisob: ${this.count}</p>
<button>Oshirish</button>
`;
}
}
customElements.define('counter-component', CounterComponent);
Ushbu komponent ichki count
o'zgaruvchisini saqlaydi va tugma bosilganda displeyni yangilaydi. connectedCallback
hodisa tinglovchisini qo'shadi va disconnectedCallback
uni olib tashlaydi.
Veb-komponentlarning ilg'or texnikalari
1. Atributlar o'rniga xususiyatlardan (properties) foydalanish
Atributlar oddiy ma'lumotlar uchun foydali bo'lsa-da, xususiyatlar (properties) ko'proq moslashuvchanlik va tur xavfsizligini taklif etadi. Siz maxsus elementingizda xususiyatlarni aniqlashingiz va ularga kirish va o'zgartirishni nazorat qilish uchun getter va setterlardan foydalanishingiz mumkin.
class MyCustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
this._data = null; // Ma'lumotlarni saqlash uchun shaxsiy xususiyatdan foydalanish
}
get data() {
return this._data;
}
set data(value) {
this._data = value;
this.renderData(); // Ma'lumotlar o'zgarganda komponentni qayta render qilish
}
connectedCallback() {
// Dastlabki renderlash
this.renderData();
}
renderData() {
// Ma'lumotlarga asoslanib Soya DOMni yangilash
this.shadow.innerHTML = `<p>Ma'lumotlar: ${JSON.stringify(this._data)}</p>`;
}
}
customElements.define('my-data-element', MyCustomElement);
Keyin siz data
xususiyatini to'g'ridan-to'g'ri JavaScriptda o'rnatishingiz mumkin:
const element = document.querySelector('my-data-element');
element.data = { name: 'John Doe', age: 30 };
2. Aloqa uchun hodisalardan (events) foydalanish
Maxsus hodisalar veb-komponentlarning bir-biri bilan va tashqi dunyo bilan aloqa qilishining kuchli usulidir. Siz komponentingizdan maxsus hodisalarni yuborishingiz va ularni ilovangizning boshqa qismlarida tinglashingiz mumkin.
class MyCustomElement extends HTMLElement {
// ... konstruktor, connectedCallback ...
dispatchCustomEvent() {
const event = new CustomEvent('my-custom-event', {
detail: { message: 'Komponentdan salom!' },
bubbles: true, // Hodisaning DOM daraxti bo'ylab yuqoriga ko'tarilishiga ruxsat berish
composed: true // Hodisaning soya DOM chegarasidan o'tishiga ruxsat berish
});
this.dispatchEvent(event);
}
}
customElements.define('my-event-element', MyCustomElement);
// Ota-hujjatda maxsus hodisani tinglash
document.addEventListener('my-custom-event', (event) => {
console.log('Maxsus hodisa qabul qilindi:', event.detail.message);
});
3. Soya DOM (Shadow DOM) uslublari
Soya DOM uslub inkapsulyatsiyasini ta'minlaydi, bu esa uslublarning komponentga kirishini yoki undan chiqib ketishini oldini oladi. Siz veb-komponentlaringizni Soya DOM ichidagi CSS yordamida uslublashingiz mumkin.
Inline uslublar:
class MyCustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
this.shadow.innerHTML = `
<style>
p {
color: blue;
}
</style>
<p>Bu uslub berilgan paragraf.</p>
`;
}
}
Tashqi uslublar jadvallari:
Siz Soya DOMga tashqi uslublar jadvallarini ham yuklashingiz mumkin:
class MyCustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
const linkElem = document.createElement('link');
linkElem.setAttribute('rel', 'stylesheet');
linkElem.setAttribute('href', 'my-component.css');
this.shadow.appendChild(linkElem);
this.shadow.innerHTML += '<p>Bu uslub berilgan paragraf.</p>';
}
}
Xulosa
Veb-komponent hayot siklini o'zlashtirish zamonaviy veb-ilovalar uchun mustahkam va qayta ishlatiladigan komponentlarni yaratish uchun zarurdir. Turli hayot sikli metodlarini tushunish va eng yaxshi amaliyotlardan foydalanish orqali siz texnik xizmat ko'rsatish oson, samarali va ilovangizning boshqa qismlari bilan muammosiz integratsiyalashadigan komponentlarni yaratishingiz mumkin. Ushbu qo'llanma veb-komponent hayot siklining keng qamrovli sharhini, jumladan, batafsil tushuntirishlar, amaliy misollar va ilg'or texnikalarni taqdim etdi. Veb-komponentlarning kuchidan foydalaning va modulli, texnik xizmat ko'rsatish oson va kengaytiriladigan veb-ilovalarni yarating.
Qo'shimcha o'rganish uchun:
- MDN Web Docs: Veb-komponentlar va maxsus elementlar bo'yicha keng qamrovli hujjatlar.
- WebComponents.org: Veb-komponentlar ishlab chiquvchilari uchun hamjamiyat tomonidan boshqariladigan manba.
- LitElement: Tez va yengil veb-komponentlar yaratish uchun oddiy asosiy sinf.