React PlatoBlockchain Veri Zekasıyla Bile Çalışan Birlikte Çalışabilen Web Bileşenleri Oluşturmak. Dikey Arama. Ai.

React ile Bile Çalışabilen Birlikte Çalışabilir Web Bileşenleri Oluşturma

Birkaç yıldan uzun süredir web geliştiricileri olan bizler, muhtemelen birden fazla JavaScript çerçevesi kullanarak kod yazdık. Dışarıdaki tüm seçeneklerle - React, Svelte, Vue, Angular, Solid - neredeyse kaçınılmaz. Çerçeveler arasında çalışırken uğraşmamız gereken en sinir bozucu şeylerden biri, tüm bu düşük seviyeli UI bileşenlerini yeniden oluşturmaktır: düğmeler, sekmeler, açılır menüler, vb. Özellikle sinir bozucu olan şey, bunları genellikle tek bir çerçevede tanımlamamızdır. , React deyin, ancak Svelte'de bir şey inşa etmek istiyorsak onları yeniden yazmamız gerekiyor. Veya Vue. Veya Katı. Ve benzeri.

Bu düşük seviyeli UI bileşenlerini bir kez, çerçeveden bağımsız bir şekilde tanımlayıp, bunları çerçeveler arasında yeniden kullanabilsek daha iyi olmaz mıydı? Elbette olurdu! Ve biz yapabiliriz; web bileşenleri yoludur. Bu gönderi size nasıl olduğunu gösterecek.

Şu an itibariyle, web bileşenleri için SSR hikayesi biraz eksik. Bildirime dayalı gölge DOM (DSD), bir web bileşeninin sunucu tarafında nasıl oluşturulduğudur, ancak bu yazı itibariyle Next, Remix veya SvelteKit gibi favori uygulama çerçevelerinizle entegre değildir. Bu sizin için bir gereklilikse, DSD'nin en son durumunu kontrol ettiğinizden emin olun. Ancak aksi takdirde, SSR kullandığınız bir şey değilse okumaya devam edin.

İlk olarak, biraz bağlam

Web Bileşenleri, temelde kendinizi tanımladığınız HTML öğeleridir. <yummy-pizza> ya da her neyse, sıfırdan. Burada CSS-Tricks'te (dahil Caleb Williams tarafından kapsamlı bir dizi ve John Rhea tarafından) ancak süreci kısaca gözden geçireceğiz. Esasen, bir JavaScript sınıfı tanımlarsınız, onu miras alırsınız. HTMLElementve ardından web bileşeninin sahip olduğu özellikleri, öznitelikleri ve stilleri ve elbette en sonunda kullanıcılarınıza sunacağı işaretlemeyi tanımlayın.

Belirli bir bileşene bağlı olmayan özel HTML öğeleri tanımlayabilmek heyecan vericidir. Ancak bu özgürlük aynı zamanda bir sınırlamadır. Herhangi bir JavaScript çerçevesinden bağımsız olarak var olmak, bu JavaScript çerçeveleriyle gerçekten etkileşime giremeyeceğiniz anlamına gelir. Bazı verileri alan ve ardından bazılarını oluşturan bir React bileşeni düşünün. diğer Verileri ileterek bileşeni reaksiyona sokun. Bir web bileşeni, bir React bileşeninin nasıl oluşturulacağını bilmediğinden, bu gerçekten bir web bileşeni olarak çalışmaz.

Web bileşenleri özellikle şu şekilde üstündür: yaprak bileşenleri. yaprak bileşenleri bir bileşen ağacında oluşturulacak son şeydir. Bunlar, bazı sahne malzemeleri alan ve bazılarını oluşturan bileşenlerdir. UI. Bunlar değil bileşen ağacınızın ortasında oturan, verileri ileten, bağlamı belirleyen vb. bileşenler — yalnızca saf parçalar UI Bu, uygulamanın geri kalanına hangi JavaScript çerçevesinin güç verdiğinden bağımsız olarak aynı görünecektir.

Oluşturduğumuz web bileşeni

Bir düğme gibi sıkıcı (ve yaygın) bir şey inşa etmek yerine, biraz farklı bir şey inşa edelim. Benim .. De Mesaj yükleniyor İçeriğin yeniden akışını önlemek için bulanık görüntü önizlemeleri kullanmaya ve resimlerimiz yüklenirken kullanıcılar için uygun bir kullanıcı arayüzü sağlamaya baktık. Görüntülerimizin bulanık, bozulmuş sürümlerini kodlayan ve gerçek görüntü yüklenirken bunu kullanıcı arayüzümüzde gösteren base64'e baktık. Ayrıca, adı verilen bir araç kullanarak inanılmaz derecede kompakt, bulanık önizlemeler oluşturmaya da baktık. bulanıklık.

Bu gönderi size bu önizlemeleri nasıl oluşturacağınızı ve bunları bir React projesinde nasıl kullanacağınızı gösterdi. Bu gönderi, bir web bileşeninden bu önizlemelerin nasıl kullanılacağını gösterecek, böylece onlar tarafından kullanılabilecekler. herhangi JavaScript çerçevesi.

Ancak koşabilmemiz için önce yürümemiz gerekiyor, bu yüzden web bileşenlerinin tam olarak nasıl çalıştığını görmek için önce önemsiz ve aptalca bir şeyden geçeceğiz.

Bu gönderideki her şey, herhangi bir alet kullanmadan vanilya web bileşenleri oluşturacaktır. Bu, kodun bir miktar ortak özelliği olacağı, ancak takip edilmesi nispeten kolay olması gerektiği anlamına gelir. Gibi araçlar Lit or Şablon (Stencil) Uygulama web bileşenleri oluşturmak için tasarlanmıştır ve bu kazan plakasının çoğunu çıkarmak için kullanılabilir. Onları kontrol etmenizi rica ediyorum! Ancak bu yazı için, başka bir bağımlılığı tanıtmak ve öğretmek zorunda kalmamak karşılığında biraz daha fazla kalıp levhasını tercih edeceğim.

Basit bir sayaç bileşeni

JavaScript bileşenlerinin klasik “Merhaba Dünyasını” oluşturalım: bir sayaç. Bir değer ve bu değeri artıran bir düğme oluşturacağız. Basit ve sıkıcı, ancak mümkün olan en basit web bileşenine bakmamıza izin verecek.

Bir web bileşeni oluşturmak için ilk adım, bir JavaScript sınıfı oluşturmaktır. HTMLElement:

class Counter extends HTMLElement {}

Son adım, web bileşenini kaydettirmektir, ancak yalnızca henüz kaydetmemişsek:

if (!customElements.get("counter-wc")) { customElements.define("counter-wc", Counter);
}

Ve tabii ki, onu yapın:

<counter-wc></counter-wc>

Ve aradaki her şey, web bileşeninin istediğimizi yapmasını sağlamak. Yaygın bir yaşam döngüsü yöntemi, connectedCallback, web bileşenimiz DOM'a eklendiğinde tetiklenir. Bu yöntemi, istediğimiz içeriği oluşturmak için kullanabiliriz. Unutmayın, bu bir JS sınıfıdır. HTMLElementyani bizim this value zaten bildiğiniz ve sevdiğiniz tüm normal DOM işleme yöntemleriyle birlikte web bileşeni öğesinin kendisidir.

En basitinden şunu yapabiliriz:

class Counter extends HTMLElement { connectedCallback() { this.innerHTML = "<div style='color: green'>Hey</div>"; }
} if (!customElements.get("counter-wc")) { customElements.define("counter-wc", Counter);
}

…bu gayet iyi çalışacak.

Yeşil "hey" kelimesi.
React ile Bile Çalışabilen Birlikte Çalışabilir Web Bileşenleri Oluşturma

Gerçek içerik ekleme

Biraz faydalı, etkileşimli içerik ekleyelim. ihtiyacımız var <span> geçerli sayı değerini tutmak ve bir <button> sayacı artırmak için Şimdilik, bu içeriği yapıcımızda oluşturacağız ve web bileşeni aslında DOM'deyken onu ekleyeceğiz:

constructor() { super(); const container = document.createElement('div'); this.valSpan = document.createElement('span'); const increment = document.createElement('button'); increment.innerText = 'Increment'; increment.addEventListener('click', () => { this.#value = this.#currentValue + 1; }); container.appendChild(this.valSpan); container.appendChild(document.createElement('br')); container.appendChild(increment); this.container = container;
} connectedCallback() { this.appendChild(this.container); this.update();
}

Manuel DOM oluşturma işleminden gerçekten bıktıysanız, ayarlayabileceğinizi unutmayın. innerHTML, hatta bir kez web bileşeni sınıfınızın statik özelliği olarak bir şablon öğesi oluşturun, onu klonlayın ve yeni web bileşeni örnekleri için içeriği ekleyin. Muhtemelen düşünmediğim başka seçenekler de vardır veya her zaman aşağıdaki gibi bir web bileşeni çerçevesi kullanabilirsiniz. Lit or Şablon (Stencil) Uygulama. Ancak bu gönderi için basit tutmaya devam edeceğiz.

Devam edersek, adında ayarlanabilir bir JavaScript sınıfı özelliğine ihtiyacımız var. value

#currentValue = 0; set #value(val) { this.#currentValue = val; this.update();
}

Değeri tutmak için ikinci bir özellik ile birlikte bir ayarlayıcıya sahip standart bir sınıf özelliğidir. Eğlenceli bir bükülme, bu değerler için özel JavaScript sınıfı özellik sözdizimini kullanmamdır. Bu, web bileşenimiz dışındaki hiç kimsenin bu değerlere asla dokunamayacağı anlamına gelir. Bu standart JavaScript'tir tüm modern tarayıcılarda desteklenen, bu yüzden kullanmaktan korkmayın.

Veya aramaktan çekinmeyin _value Eğer tercih edersen. Ve son olarak, bizim update yöntem:

update() { this.valSpan.innerText = this.#currentValue;
}

İşe yarıyor!

Sayaç web bileşeni.
React ile Bile Çalışabilen Birlikte Çalışabilir Web Bileşenleri Oluşturma

Açıkçası bu, ölçekte tutmak isteyeceğiniz bir kod değil. İşte tam bir çalışma örneği daha yakından bakmak isterseniz. Söylediğim gibi, Lit ve Stencil gibi araçlar bunu kolaylaştırmak için tasarlandı.

Biraz daha işlevsellik ekleme

Bu gönderi, web bileşenlerine derinlemesine bir dalış değildir. Tüm API'leri ve yaşam döngülerini kapsamayacağız; örtmeyeceğiz bile gölge kökleri veya yuvaları. Bu konularda sonsuz içerik var. Buradaki amacım, biraz ilgi uyandırmak için yeterince iyi bir giriş sağlamak ve aslında bazı yararlı rehberlik sağlamak. kullanma Bildiğiniz ve sevdiğiniz popüler JavaScript çerçevelerine sahip web bileşenleri.

Bu amaçla, karşı web bileşenimizi biraz geliştirelim. hadi kabul etsin color öznitelik, görüntülenen değerin rengini kontrol etmek için. Bir de kabul etmesini sağlayalım increment özelliği, bu web bileşeninin tüketicileri, bir seferde 2, 3, 4 artırmasını sağlayabilir. Ve bu durum değişikliklerini yönlendirmek için yeni sayacımızı bir Svelte sanal alanında kullanalım - birazdan React'e geçeceğiz.

Daha önce olduğu gibi aynı web bileşeniyle başlayacağız ve bir renk niteliği ekleyeceğiz. Web bileşenimizi bir özniteliği kabul edecek ve yanıtlayacak şekilde yapılandırmak için statik bir observedAttributes web bileşenimizin dinlediği öznitelikleri döndüren özellik.

static observedAttributes = ["color"];

Bunu yerine koyarak, bir ekleyebiliriz attributeChangedCallback içinde listelenen özelliklerden herhangi biri olduğunda çalışacak olan yaşam döngüsü yöntemi observedAttributes ayarlanır veya güncellenir.

attributeChangedCallback(name, oldValue, newValue) { if (name === "color") { this.update(); }
}

Şimdi güncelliyoruz update aslında kullanma yöntemi:

update() { this.valSpan.innerText = this._currentValue; this.valSpan.style.color = this.getAttribute("color") || "black";
}

Son olarak bizimkileri ekleyelim increment özelliği:

increment = 1;

Basit ve mütevazı.

Svelte'de sayaç bileşenini kullanma

Az önce yaptığımızı kullanalım. Svelte uygulama bileşenimize gideceğiz ve şunun gibi bir şey ekleyeceğiz:

<script> let color = "red";
</script> <style> main { text-align: center; }
</style> <main> <select bind:value={color}> <option value="red">Red</option> <option value="green">Green</option> <option value="blue">Blue</option> </select> <counter-wc color={color}></counter-wc>
</main>

Ve çalışıyor! Sayacımız işlemeler, artışlar ve açılır menü rengi günceller. Gördüğünüz gibi, color niteliğini Svelte şablonumuzda oluşturuyoruz ve değer değiştiğinde, Svelte aramanın ayak işlerini hallediyor. setAttribute temel web bileşeni örneğimizde. Burada özel bir şey yok: bu, öznitelikleri için zaten yaptığı şeyin aynısı. herhangi HTML öğesi.

ile işler biraz ilginçleşiyor increment pervane. Bu değil web bileşenimizdeki bir öznitelik; web bileşeninin sınıfında bir destektir. Bu, web bileşeni örneğinde ayarlanması gerektiği anlamına gelir. Sabırlı olun, çünkü işler birazdan çok daha basit hale gelecek.

İlk olarak, Svelte bileşenimize bazı değişkenler ekleyeceğiz:

let increment = 1;
let wcInstance;

Bir sayaç bileşeninin güç merkezimiz, 1 veya 2 ile artırmanıza izin verecektir:

<button on:click={() => increment = 1}>Increment 1</button>
<button on:click={() => increment = 2}>Increment 2</button>

Ancak, teoride, web bileşenimizin gerçek örneğini almamız gerekiyor. Bu, her eklediğimizde her zaman yaptığımızla aynı şeydir. ref React ile. Svelte ile, bu basit bind:this direktif:

<counter-wc bind:this={wcInstance} color={color}></counter-wc>

Şimdi, Svelte şablonumuzda, bileşenimizin artış değişkenindeki değişiklikleri dinliyoruz ve alttaki web bileşeni özelliğini ayarlıyoruz.

$: { if (wcInstance) { wcInstance.increment = increment; }
}

test edebilirsin bu canlı demoda.

Açıkçası, yönetmemiz gereken her web bileşeni veya destek için bunu yapmak istemiyoruz. ayarlayabilsek güzel olmaz mıydı increment bizim web bileşenimizde, işaretlemede, normalde bileşen aksesuarları için yaptığımız gibi ve buna sahibiz, bilirsiniz, sadece iş? Diğer bir deyişle, tüm kullanımlarını silebilseydik iyi olurdu. wcInstance ve bunun yerine bu daha basit kodu kullanın:

<counter-wc increment={increment} color={color}></counter-wc>

Yapabileceğimiz ortaya çıktı. Bu kod çalışır; Tüm bu ayak işlerini bizim için Svelte hallediyor. Bu demoda kontrol edin. Bu, hemen hemen tüm JavaScript çerçeveleri için standart davranıştır.

Peki neden size web bileşeninin pervanesini manuel olarak ayarlamanın yolunu gösterdim? İki neden: Bu şeylerin nasıl çalıştığını anlamak faydalıdır ve bir an önce bunun tüm JavaScript çerçeveleri için "hemen hemen" işe yaradığını söylemiştim. Ancak, az önce gördüğümüz gibi, çıldırtıcı bir şekilde web bileşeni destek ayarını desteklemeyen bir çerçeve var.

React farklı bir canavar

React PlatoBlockchain Veri Zekasıyla Bile Çalışan Birlikte Çalışabilen Web Bileşenleri Oluşturmak. Dikey Arama. Ai.
React ile Bile Çalışabilen Birlikte Çalışabilir Web Bileşenleri Oluşturma

Tepki. Gezegendeki en popüler JavaScript çerçevesi, web bileşenleriyle temel birlikte çalışmayı desteklemez. Bu, React'e özgü, iyi bilinen bir sorundur. İlginç bir şekilde, bu aslında React'in deneysel dalında düzeltildi, ancak bir nedenden dolayı sürüm 18 ile birleştirilmedi. ilerlemesini takip et. Ve bunu kendin deneyebilirsin canlı demo.

Çözüm, elbette, bir ref, web bileşeni örneğini alın ve manuel olarak ayarlayın increment bu değer değiştiğinde. Şuna benziyor:

import React, { useState, useRef, useEffect } from 'react';
import './counter-wc'; export default function App() { const [increment, setIncrement] = useState(1); const [color, setColor] = useState('red'); const wcRef = useRef(null); useEffect(() => { wcRef.current.increment = increment; }, [increment]); return ( <div> <div className="increment-container"> <button onClick={() => setIncrement(1)}>Increment by 1</button> <button onClick={() => setIncrement(2)}>Increment by 2</button> </div> <select value={color} onChange={(e) => setColor(e.target.value)}> <option value="red">Red</option> <option value="green">Green</option> <option value="blue">Blue</option> </select> <counter-wc ref={wcRef} increment={increment} color={color}></counter-wc> </div> );
}

Tartıştığımız gibi, bunu her web bileşeni özelliği için manuel olarak kodlamak ölçeklenebilir değildir. Ama hepsi kaybolmadı çünkü birkaç seçeneğimiz var.

1. Seçenek: Nitelikleri her yerde kullanın

Niteliklerimiz var. Yukarıdaki React demosuna tıkladıysanız, increment pervane çalışmıyordu, ancak renk doğru şekilde değişti. Her şeyi niteliklerle kodlayamaz mıyız? Üzgünüm hayır. Öznitelik değerleri yalnızca dize olabilir. Burası yeterince iyi ve bu yaklaşımla biraz daha ileri gidebiliriz. gibi sayılar increment dizelere ve dizelerden dönüştürülebilir. Hatta JSON nesneleri dizeleyebilir/ayrıştırabiliriz. Ama sonunda bir işlevi bir web bileşenine geçirmemiz gerekecek ve bu noktada seçeneklerimiz kalmayacak.

Seçenek 2: Sarın

Bilgisayar bilimindeki herhangi bir sorunu bir düzey dolaylılık ekleyerek çözebileceğinize dair eski bir söz vardır (çok fazla dolaylılık düzeyi sorunu hariç). Bu aksesuarları ayarlamak için kullanılan kod oldukça öngörülebilir ve basittir. Ya onu bir kütüphanede saklarsak? Lit'in arkasındaki akıllı insanlar tek bir çözümü var. Bu kütüphane, siz ona bir web bileşeni verdikten sonra sizin için yeni bir React bileşeni oluşturur ve ihtiyaç duyduğu özellikleri listeler. Zeki olsa da, bu yaklaşımın hayranı değilim.

Web bileşenlerinin manuel olarak oluşturulmuş React bileşenleriyle birebir eşleştirilmesi yerine, tercih ettiğim şey sadece bir Web bileşenimize geçtiğimiz React componenti etiket adı To (counter-wc bizim durumumuzda) - tüm nitelikler ve özelliklerle birlikte - ve bu bileşenin web bileşenimizi oluşturması için şunu ekleyin: ref, sonra bir pervanenin ve bir niteliğin ne olduğunu anlayın. Bana göre ideal çözüm bu. Bunu yapan bir kitaplık bilmiyorum, ancak oluşturulması basit olmalı. Bir şans verelim!

Bu kullanım arıyoruz:

<WcWrapper wcTag="counter-wc" increment={increment} color={color} />

wcTag web bileşeni etiket adıdır; geri kalanı, iletilmesini istediğimiz özellikler ve niteliklerdir.

İşte benim uygulama gibi görünüyor:

import React, { createElement, useRef, useLayoutEffect, memo } from 'react'; const _WcWrapper = (props) => { const { wcTag, children, ...restProps } = props; const wcRef = useRef(null); useLayoutEffect(() => { const wc = wcRef.current; for (const [key, value] of Object.entries(restProps)) { if (key in wc) { if (wc[key] !== value) { wc[key] = value; } } else { if (wc.getAttribute(key) !== value) { wc.setAttribute(key, value); } } } }); return createElement(wcTag, { ref: wcRef });
}; export const WcWrapper = memo(_WcWrapper);

En ilginç satır sonunda:

return createElement(wcTag, { ref: wcRef });

React'te dinamik bir adla bir öğeyi bu şekilde oluşturuyoruz. Aslında, React'in normalde JSX'i içine aktardığı şey budur. Tüm div'lerimiz dönüştürülür createElement("div") aramalar. Normalde bu API'yi doğrudan çağırmamız gerekmez, ancak ihtiyacımız olduğunda oradadır.

Bunun ötesinde, bir layout efektini çalıştırmak ve bileşenimize ilettiğimiz her prop arasında döngü yapmak istiyoruz. Hepsini dolaşıyoruz ve bunun bir özellik olup olmadığını kontrol ediyoruz. in web bileşeni örnek nesnesini ve ayrıca sınıf prototipinde oluşan alıcıları/ayarlayıcıları yakalayacak olan prototip zincirini kontrol edip etmediğini kontrol edin. Böyle bir özellik yoksa, bunun bir öznitelik olduğu varsayılır. Her iki durumda da, yalnızca değer gerçekten değiştiyse ayarlarız.

neden kullandığımızı merak ediyorsanız useLayoutEffect yerine useEffect, bunun nedeni, içeriğimiz oluşturulmadan önce bu güncellemeleri hemen çalıştırmak istememizdir. Ayrıca, bizim için bir bağımlılık dizimiz olmadığını unutmayın. useLayoutEffect; bu, bu güncellemeyi çalıştırmak istediğimiz anlamına gelir her render. React yeniden oluşturma eğiliminde olduğundan bu riskli olabilir çok. Her şeyi içine sararak bunu iyileştiriyorum React.memo. Bu aslında modern versiyonu React.PureComponent, bu, bileşenin yalnızca gerçek öğelerinden herhangi biri değiştiğinde yeniden oluşturulacağı anlamına gelir - ve bunun basit bir eşitlik kontrolü ile olup olmadığını kontrol eder.

Buradaki tek risk, mutasyona uğrattığınız bir nesne prop'unu yeniden atamadan doğrudan geçiyorsanız, güncellemeleri görmeyeceksiniz. Ancak bu, özellikle React topluluğunda pek önerilmez, bu yüzden bu konuda endişelenmem.

Devam etmeden önce son bir şey söylemek istiyorum. Kullanımın nasıl göründüğünden memnun olmayabilirsiniz. Yine, bu bileşen şu şekilde kullanılır:

<WcWrapper wcTag="counter-wc" increment={increment} color={color} />

Spesifik olarak, web bileşeni etiket adını <WcWrapper> bileşen ve bunun yerine tercih @lit-labs/react Her web bileşeni için yeni bir bireysel React bileşeni oluşturan yukarıdaki paket. Bu tamamen adil ve seni en rahat ettiğin şeyi kullanmaya teşvik ediyorum. Ama benim için bu yaklaşımın bir avantajı, silmek. Bir mucize eseri React, uygun web bileşeni işlemeyi deneysel dallarından main yarın, yukarıdaki kodu bundan değiştirebileceksiniz:

<WcWrapper wcTag="counter-wc" increment={increment} color={color} />

…buna:

<counter-wc ref={wcRef} increment={increment} color={color} />

Muhtemelen bunu her yerde yapmak için tek bir kod modu bile yazabilir ve ardından silebilirsiniz. <WcWrapper> tamamen. Aslında şunu çizin: genel bir arama yapın ve bir RegEx ile değiştirin muhtemelen işe yarayacaktır.

Hayata geçirme

Biliyorum, buraya gelmek için bir yolculuk yapmış gibi görünüyor. Hatırlarsanız, asıl amacımız, incelediğimiz resim ön izleme kodunu dosyamda almaktı. Mesaj yükleniyor, ve herhangi bir JavaScript çerçevesinde kullanılabilmesi için bir web bileşenine taşıyın. React'in uygun birlikte çalışma eksikliği, karışıma çok fazla ayrıntı ekledi. Ancak artık bir web bileşeninin nasıl oluşturulacağı ve kullanılacağı konusunda yeterince bilgi sahibi olduğumuza göre, uygulama neredeyse iklim karşıtı olacak.

Tüm web bileşenini buraya bırakacağım ve bazı ilginç kısımlardan bahsedeceğim. Eylem halinde görmek isterseniz, işte bir çalışma demosu. En sevdiğim üç programlama diliyle ilgili en sevdiğim üç kitap arasında geçiş yapacak. Her kitabın URL'si her seferinde benzersiz olacaktır, bu nedenle önizlemeyi görebilirsiniz, ancak muhtemelen gerçekleşen şeyleri gerçekten görmek için DevTools Ağı sekmenizdeki şeyleri kısmak isteyeceksiniz.

Kodun tamamını görüntüle
class BookCover extends HTMLElement { static observedAttributes = ['url']; attributeChangedCallback(name, oldValue, newValue) { if (name === 'url') { this.createMainImage(newValue); } } set preview(val) { this.previewEl = this.createPreview(val); this.render(); } createPreview(val) { if (typeof val === 'string') { return base64Preview(val); } else { return blurHashPreview(val); } } createMainImage(url) { this.loaded = false; const img = document.createElement('img'); img.alt = 'Book cover'; img.addEventListener('load', () =&gt; { if (img === this.imageEl) { this.loaded = true; this.render(); } }); img.src = url; this.imageEl = img; } connectedCallback() { this.render(); } render() { const elementMaybe = this.loaded ? this.imageEl : this.previewEl; syncSingleChild(this, elementMaybe); }
}

İlk olarak ilgilendiğimiz özelliği kaydederiz ve değiştiğinde tepki veririz:

static observedAttributes = ['url']; attributeChangedCallback(name, oldValue, newValue) { if (name === 'url') { this.createMainImage(newValue); }
}

Bu, yalnızca yüklendiğinde gösterilecek olan görüntü bileşenimizin oluşturulmasına neden olur:

createMainImage(url) { this.loaded = false; const img = document.createElement('img'); img.alt = 'Book cover'; img.addEventListener('load', () => { if (img === this.imageEl) { this.loaded = true; this.render(); } }); img.src = url; this.imageEl = img;
}

Ardından, base64 önizleme dizimiz veya bizim önizleme dizimiz olabilen önizleme özelliğimiz var. blurhash paket:

set preview(val) { this.previewEl = this.createPreview(val); this.render();
} createPreview(val) { if (typeof val === 'string') { return base64Preview(val); } else { return blurHashPreview(val); }
}

Bu, ihtiyacımız olan yardımcı işleve göre değişir:

function base64Preview(val) { const img = document.createElement('img'); img.src = val; return img;
} function blurHashPreview(preview) { const canvasEl = document.createElement('canvas'); const { w: width, h: height } = preview; canvasEl.width = width; canvasEl.height = height; const pixels = decode(preview.blurhash, width, height); const ctx = canvasEl.getContext('2d'); const imageData = ctx.createImageData(width, height); imageData.data.set(pixels); ctx.putImageData(imageData, 0, 0); return canvasEl;
}

Ve son olarak, bizim render yöntem:

connectedCallback() { this.render();
} render() { const elementMaybe = this.loaded ? this.imageEl : this.previewEl; syncSingleChild(this, elementMaybe);
}

Ve her şeyi birbirine bağlamak için birkaç yardımcı yöntem:

export function syncSingleChild(container, child) { const currentChild = container.firstElementChild; if (currentChild !== child) { clearContainer(container); if (child) { container.appendChild(child); } }
} export function clearContainer(el) { let child; while ((child = el.firstElementChild)) { el.removeChild(child); }
}

Bunu bir çerçeve içinde inşa edersek ihtiyacımız olandan biraz daha fazla standart, ancak bunun tersi, bunu istediğimiz herhangi bir çerçevede yeniden kullanabilmemizdir - tartıştığımız gibi, React şimdilik bir sarmalayıcıya ihtiyaç duyacaktır. .

Döküntüler

Lit'in React sarmalayıcısından daha önce bahsetmiştim. Ancak kendinizi Stencil kullanırken bulursanız, aslında bir sadece React için ayrı çıkış hattı. Ve Microsoft'taki iyi insanlar da Lit'in sargısına benzer bir şey yarattı, Hızlı web bileşeni kitaplığına eklenmiştir.

Bahsettiğim gibi, adı React olmayan tüm çerçeveler sizin için web bileşeni özelliklerini ayarlayacaktır. Sadece bazılarının bazı özel sözdizimi tatları olduğunu unutmayın. Örneğin, Solid.js ile, <your-wc value={12}> her zaman bunu varsayar value ile geçersiz kılabileceğiniz bir özelliktir. attr önek, gibi <your-wc attr:value={12}>.

Tamamlayan

Web bileşenleri, web geliştirme ortamının ilginç, genellikle yeterince kullanılmayan bir parçasıdır. Kullanıcı arayüzünüzü veya "yaprak" bileşenlerinizi yöneterek herhangi bir JavaScript çerçevesine olan bağımlılığınızı azaltmaya yardımcı olabilirler. Bunları web bileşenleri olarak oluşturmak – Svelte veya React bileşenlerinin aksine – o kadar ergonomik olmayacak, ancak iyi tarafı, geniş çapta yeniden kullanılabilir olmaları.


React ile Bile Çalışabilen Birlikte Çalışabilir Web Bileşenleri Oluşturma aslen yayınlandı CSS Hileleri. Malısın bülteni al.

Zaman Damgası:

Den fazla CSS Püf Noktaları