Komponen Web lebih mudah dari yang Anda pikirkan

Ketika saya pergi ke konferensi dan melihat presentasi tentang topik komponen web, saya selalu berpikir bahwa itu tidak hanya elegan, tetapi juga cukup sulit. Ribuan baris JavaScript untuk menyimpan hanya 4 baris HTML. Pembicara entah mau tidak mau menyembunyikan sejumlah besar kode JS di balik hal-hal sederhana, atau menyelami detail yang rumit, lalu mata saya mulai tertutup oleh kebosanan, dan saya mulai memikirkan apakah uang saku harian saya menutupi biaya camilan.





Namun, pada proyek baru-baru ini yang dibuat untuk mempelajari HTML dengan mudah (tentu saja, dengan menambahkan zombie dan lelucon konyol), saya memutuskan bahwa perlu untuk mendeskripsikan setiap elemen HTML dalam spesifikasi. Terlepas dari konferensi itu, saya pertama kali memulai dengan pendahuluan <slot>



dan <template>



elemen, dan ketika saya ingin menulis sesuatu yang menarik tentang mereka dalam proyek, saya harus mempelajari subjeknya.





Dan saat saya melangkah lebih dalam, saya menyadari bahwa Komponen Web lebih mudah dari yang saya kira.





Entah komponen web telah berkembang jauh sejak saya bermimpi ngemil di konferensi, atau saya membiarkan ketakutan awal saya menghalangi untuk benar-benar mengenal mereka, atau mungkin keduanya.





Saya di sini untuk memberi tahu Anda ya, Anda dapat membuat komponen web. Mari kita singkirkan rasa takut dan bahkan camilan di luar pintu untuk menyatukan semuanya.





Mari kita mulai dengan <template>

<template>



merupakan elemen HTML yang memungkinkan kita untuk membuat template (struktur HTML untuk komponen web).





Kode
<template>
  <p>The Zombies are coming!</p>
</template>
      
      



Elemen <template>



ini sangat penting karena memungkinkan Anda untuk menyatukan semuanya. Itu seperti pangkalan untuk rumah Anda, pangkalan dari mana segala sesuatu yang kita sebut bangunan selesai mulai dibangun. Mari gunakan cuplikan kecil kode ini untuk <apocalyptic-warning>



komponen kita yang memberi tahu kita tentang kiamat zombie yang akan datang.





Lalu ada komponen <slot>

<slot>



hanyalah elemen HTML, sama seperti <template>



. Namun dalam kasus kami, ini <slot>



mengkonfigurasi apa yang <template>



ditampilkan di halaman.





Kode
<template>
  <p>The <slot>Zombies</slot> are coming!</p>
</template>
      
      



"Zombies" ( ?) <template>



. , . "Zombies".





<slot>



placeholder



. placeholder



, , - placeholder



. - name



.





<template>
  <p>The <slot name="whats-coming">Zombies</slot> are coming!</p>
</template>
      
      



name



- , <template>



. "whats-coming" . , -, <slot>



, - , , .





-

, , ( : JS , ).





<apocalyptic-warning>
  <span slot="whats-coming">Halitosis Laden Undead Minions</span>
</apocalyptic-warning>

<template>
  <p>The <slot name="whats-coming">Zombies</slot> are coming!</p>
</template>
      
      



, ? <apocalyptic-warning>



, HTML . <span>



"whats-coming". <span>



"Zombies", .





, - , HTML , . , , -.





? , ? , . , <slot>



, JavaScript.





, JavaScript , , , , . , , .





-, -. : , .





, .





//   -   

customElements.define("apocalyptic-warning", class extends HTMLElement {
  	  //  ,          HTML 
  
  	//   ,    
    constructor() {

      //   , .   HTMLElement.      HTML .
      super();

      //  <template>      `warinng`
      let warning = document.getElementById("warningtemplate");
      
      //      `mywarning`
      let mywarning = warning.content;

      const shadowRoot = this.attachShadow({mode: "open"}).appendChild(mywarning.cloneNode(true));
    }
});
      
      



, .





const shadowRoot = this.attachShadow({mode: "open"}).appendChild(mywarning.cloneNode(true));
      
      



. -, - (this) , Shadow DOM.{ mode: open }



, JavaScript :root



Shadow DOM , - . Shadow DOM ( : HTML Node). , . , Shadow DOM , <slot>



slot , .





. -, , .





JS:





customElements.define('apocalyptic-warning',
    class extends HTMLElement {
      constructor() {
        super();
        let warning = document.getElementById('warningtemplate');
        let mywarning = warning.content;
        
         const shadowRoot = this.attachShadow({mode: 'open'}).appendChild(mywarning.cloneNode(true));
        
      }
    });
      
      



HTML:





<p>The Apocalypse will never happen!</p>
<apocalyptic-warning>
   <span slot="whats-coming">Undead</span>
</apocalyptic-warning>
<apocalyptic-warning>
   <span slot="whats-coming">Halitosis Laden Zombie Minions</span>
</apocalyptic-warning>
<template id="warningtemplate">
  <style>
    p {
      background-color: pink;
      padding: 0.5em;
      border: 1px solid red;
    }
  </style>
    <p>The <slot name="whats-coming">Zombies</slot> are coming!</p>
</template>
      
      



: Codepen





, . , CSS. , <style>



<template>



.





<template id="warningtemplate">
  <style>
    p {
      background-color: pink;
      padding: 0.5em;
      border: 1px solid red;
    }
  </style>

    <p>The <slot name="whats-coming">Zombies</slot> are coming!</p>
</template>
      
      



, , Shadow DOM.





, , , , , Shadow DOM. , Shadow DOM DOM , . - , DOM .





, , <style>,



<slot>



. , . - , CSS , , . , -, CSS.





apocalyptic-warning span {
  color: blue;
}
      
      



, CSS <template>



.





JavaScript , , , , <zombie-profile>.







customElements.define("zombie-profile",
  class extends HTMLElement {
    constructor() {
      super();
      let profile = document.getElementById("zprofiletemplate");
      let myprofile = profile.content;
      const shadowRoot = this.attachShadow({mode: "open"}).appendChild(myprofile.cloneNode(true));
    }
  }
);
      
      



HTML CSS.





<template id="zprofiletemplate">
  <style>
    img {
      width: 100%;
      max-width: 300px;
      height: auto;
      margin: 0 1em 0 0;
    }
    h2 {
      font-size: 3em;
      margin: 0 0 0.25em 0;
      line-height: 0.8;
    }
    h3 {
      margin: 0.5em 0 0 0;
      font-weight: normal;
    }
    .age, .infection-date {
      display: block;
    }
    span {
      line-height: 1.4;
    }
    .label {
      color: #555;
    }
    li, ul {
      display: inline;
      padding: 0;
    }
    li::after {
      content: ', ';
    }
    li:last-child::after {
      content: '';
    }
    li:last-child::before {
      content: ' and ';
    }
  </style>

  <div class="profilepic">
    <slot name="profile-image"><img src="https://assets.codepen.io/1804713/default.png" alt=""></slot>
  </div>

  <div class="info">
    <h2><slot name="zombie-name" part="zname">Zombie Bob</slot></h2>

    <span class="age"><span class="label">Age:</span> <slot name="z-age">37</slot></span>
    <span class="infection-date"><span class="label">Infection Date:</span> <slot name="idate">September 12, 2025</slot></span>

    <div class="interests">
      <span class="label">Interests: </span>
      <slot name="z-interests">
        <ul>
          <li>Long Walks on Beach</li>
          <li>brains</li>
          <li>defeating humanity</li>
        </ul>
      </slot>
    </div>

    <span class="z-statement"><span class="label">Apocalyptic Statement: </span> <slot name="statement">Moooooooan!</slot></span>

  </div>
</template>
      
      



CSS <zombie-profile>



CSS. , , , <template>



.





zombie-profile {
  width: calc(50% - 1em);
  border: 1px solid red;
  padding: 1em;
  margin-bottom: 2em;
  display: grid;
  grid-template-columns: 2fr 4fr;
  column-gap: 20px;
}
zombie-profile img {
  width: 100%;
  max-width: 300px;
  height: auto;
  margin: 0 1em 0 0;
}
zombie-profile li, zombie-profile ul {
  display: inline;
  padding: 0;
}
zombie-profile li::after {
  content: ', ';
}
zombie-profile li:last-child::after {
  content: '';
}
zombie-profile li:last-child::before {
  content: ' and ';
}
      
      



:





: Codepen





, , , -, . , , - , , .





Itu saja. Apa yang lebih Anda takuti sekarang: komponen web atau kiamat zombie? Di masa lalu yang tidak terlalu lama, saya bisa mengatakan bahwa komponen web, tetapi sekarang zombie adalah satu-satunya hal yang membuat saya khawatir (Yah, dan akankah uang saku harian saya menutupi biaya makanan ringan).








All Articles