ข้ามไปยังเนื้อหา

Named Slots

named slot คือ <slot> element ที่มี name attribute อยู่ใน shadow tree จับคู่กับ slot attribute บนลูกใน light DOM browser จะจับคู่ทั้งสองด้วยชื่อ และ render ลูกแต่ละตัวจาก light DOM ที่จุดแทรกที่ตรงกัน การใช้ named slot หลายตัวช่วยให้คอมโพเนนต์ตัวเดียวเปิดเผยพื้นที่เนื้อหาที่แตกต่างกันได้หลายส่วน ที่เป็นแพทเทิร์นที่พบบ่อยในคอมโพเนนต์ประเภท card, dialog และ layout

<my-card>
<span slot="header">Card Title</span>
<p slot="body">Card body text here.</p>
</my-card>
class MyCard extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>...</style>
<div class="card">
<header><slot name="header">Untitled</slot></header>
<section><slot name="body">No body.</slot></section>
</div>
`;
}
}
customElements.define('my-card', MyCard);

ลูกใน light DOM ที่มี slot attribute ซึ่ง ไม่ ตรงกับ named slot ใด ๆ ใน shadow tree จะถูกข้ามไปอย่างเงียบ ๆ คือไม่ถูก render ที่ไหนเลย นั่นหมายความว่าการพิมพ์ชื่อ slot ผิดจะทำให้เนื้อหามองไม่เห็น ดังนั้นจึงควรตรวจสอบชื่อ slot ให้ดีเมื่อ debug เนื้อหาที่หายไป

element หนึ่งสามารถมีทั้ง named slot และ default slot พร้อมกันได้ ลูกที่ตรงกับ named slot จะถูกกระจายไปยัง named slot ที่ตรงกัน ส่วนลูกที่เหลือซึ่งไม่มี slot attribute จะตกลงไปอยู่ใน default slot ทำให้สร้างคอมโพเนนต์ที่มีส่วนที่มีโครงสร้าง (header, footer) บวกกับพื้นที่เนื้อหาแบบอิสระได้อย่างง่ายดาย

ตัวเลือกBenefitCost
Named slots หลายตัวเปิดให้ผู้ใช้งานประกอบ layout เองได้อย่างยืดหยุ่น เหมาะกับคอมโพเนนต์ที่มีหลายส่วน เช่น card, dialogเพิ่ม learning curve ให้ผู้ใช้งานต้องรู้ชื่อ slot ที่ถูกต้อง พิมพ์ผิดแล้วเนื้อหาหายไปเงียบ ๆ
ผูก slot name ไว้ตัวเดียว (default slot เดี่ยว)เรียนรู้ง่าย ไม่มีโอกาสพิมพ์ชื่อ slot ผิดจำกัดความสามารถในการจัดวางหลายส่วนเนื้อหาแยกกัน
  • พิมพ์ชื่อ slot attribute ผิดหรือไม่ตรงกับ named slot ใน shadow tree — เนื้อหานั้นจะไม่ถูก render เลยแบบเงียบ ๆ ไม่มี error ใด ๆ ให้เห็น ควรตรวจสอบชื่อให้ตรงกันเสมอ
  • คาดหวังว่าจะสไตล์ descendant ของเนื้อหาที่ถูกฉายเข้า named slot ได้ทั้งหมดจาก shadow root::slotted() เลือกได้เฉพาะ element ระดับบนสุดที่ถูกฉายเข้ามาเท่านั้น ไม่ทะลุเข้าไปถึงลูกหลานของตัวเอง
  • ลืมกำหนด fallback content ให้ named slot ที่อาจไม่มีใครใส่ข้อมูลมา — ทำให้ UI ว่างเปล่าโดยไม่มีคำอธิบายเมื่อผู้ใช้งานคอมโพเนนต์ลืมใส่ slot นั้น

💡 ตัวอย่างจากของจริง

Shoelace ใช้ named slots อย่างกว้างขวางในการออกแบบ API ของคอมโพเนนต์ เช่น slot prefix/suffix ใน <sl-input> หรือ slot icon ใน <sl-button> เพื่อให้ผู้ใช้งาน inject ไอคอนหรือเนื้อหาเสริมได้อย่างยืดหยุ่น

Lit แนะนำแพทเทิร์นการใช้ named slots ในการสร้างคอมโพเนนต์แบบ composable เช่น layout component ที่มี slot header, content, footer แยกกัน

คุณกำหนดลูกใน light DOM ให้กับ named slot ที่ชื่อ 'header' ได้อย่างไร?
เกิดอะไรขึ้นกับลูกใน light DOM ที่มี slot attribute ซึ่งไม่ตรงกับ named slot ใด ๆ ใน shadow tree?
element ที่มี named slot สองตัว — 'header' และ 'footer' — และ default slot หนึ่งตัว สามารถรับลูกจาก light DOM ได้พร้อมกันกี่ตัว?