Template Element
Thẻ <template> cho phép ta tạo ra một tập hợp các element có thể tái sử dụng ở nhiều nơi trong trang web.
<template id="my-paragraph">
<p>My paragraph</p>
</template>Thẻ <template> và nội dung bên trong nó chỉ hiện ra giao diện khi chúng ta gắn nó vào original DOM tree.
let template = document.getElementById("my-paragraph")
let templateContent = template.content
document.body.appendChild(templateContent)Có thể nói, thẻ <template> có tính chất giống như một shadow host của Shadow DOM. Bởi vì nội dung bên trong của shadow host được cô lập với thế giới bên ngoài. Chỉ khi nào chúng ta append shadow host này vào original DOM tree thì nội dung bên trong nó mới được hiển thị ra giao diện.
Hình bên dưới mô tả giai đoạn sau khi shadow host (tức <template>) đã được append vào cây DOM gốc:

Definition
Một web component là một thẻ <template> mà chứa bên trong nó là các element và stylesheet. Các element và stylesheet này sẽ được cô lập với thế giới bên ngoài. Một web component còn được xem là một custom element.
Để tạo ra một custom element, đầu tiên ta cần tạo ra một template với thuộc tính id cho biết tên của custom element đó.
Ví dụ, ta tạo ra một custom element có tên là my-paragraph bao gồm một thẻ <p> và một thẻ <style> chứa các stylesheet cho thẻ <p> đó.
<template id="my-paragraph">
<p>My paragraph</p>
<style>
p {
color: white;
background-color: #666;
padding: 5px;
}
</style>
</template>Sau đó, ở phía JavaScript, ta cần phải tạo ra một lớp đối tượng cho custom element này:
class MyParagraph extends HTMLElement {
constructor() {
// Allways call the super function
super()
// Create a shadow root with open mode
const shadowRoot = this.attachShadow({ mode: "open" })
// Get the template content
const templateContent = document.getElementById("my-paragraph").content
// Append the clone template content to the shadow root
shadowRoot.appendChild(templateContent.cloneNode(true))
}
}Thêm vào danh sách các custom element như sau:
customElements.define("my-paragraph", MyParagraph) //(custom element name, custom element class)Cuối cùng, để sử dụng, ta chỉ việc gọi ra custom element bằng tên của nó trong file HTML:
<my-paragraph></my-paragraph>Adding Flexibility with Slots
Để có thể khiến cho nội dung bên trong một template có thể tùy biến, ta sẽ sử dụng các thẻ <slot>.
- Mỗi thẻ
<slot>sẽ đi kèm với thuộc tínhnamegiúp khai báo tên của slot đó. - Content bên trong thẻ
<slot>là fallback content, được hiển thị khi trình duyệt không hỗ trợ slots hoặc custom element không định nghĩa slot có tên tương ứng. - Thẻ
<slot>có thể nằm ở bên trong hoặc bên ngoài những element khác.
<template id="my-paragraph">
<p><slot name="my-text">My default text</slot></p>
</template>Để định nghĩa nội dung của một slot bằng một element nào đó, ta cần thêm vào element đó thuộc tính slot với tên là tên của slot tương ứng.
<my-paragraph>
<span slot="my-text">Let's have some different text!</span>
</my-paragraph>Ví dụ trên sẽ định nghĩa nội dung của slot my-text bằng một thẻ <span>. Thẻ <span> sẽ được thế chỗ vào thẻ <slot> ở trong template my-paragraph.
Chúng ta có thể sử dụng các element khác ngoài thẻ <span>, chẳng hạn như thẻ <ul> như sau:
<my-paragraph>
<ul slot="my-text">
<li>Let's have some different text!</li>
<li>In a list!</li>
</ul>
</my-paragraph>Attention
Thẻ
<slot>không có tên (không có thuộc tínhname) sẽ được thế chỗ bởi tất cả các element bên trong custom element mà không có thuộc tínhslot.