การวางแนวของคอมโพเนนต์เว็บ

Web Components คือองค์ประกอบที่กำหนดเอง, Shadow DOM และเทมเพลต HTML ซึ่งเป็นองค์ประกอบพื้นฐานของแพลตฟอร์มสำหรับคอมโพเนนต์ที่นำกลับมาใช้ใหม่ได้และไม่ขึ้นอยู่กับเฟรมเวิร์ก โดยมาร์กอัปและสไตล์จะได้รับการแคปซูลจากเอกสาร ใช้สำหรับระบบการออกแบบ วิดเจ็ตที่ฝังได้ และ UI แบบครบวงจร

กฎด้านล่างนี้เป็นกฎที่ครอบคลุมหลายด้าน ดูคำแนะนำที่เจาะจงสำหรับงานที่ทำอยู่ โดยแต่ละคำแนะนำจะระบุบริบทที่จำเป็นและบันทึก API และข้อผิดพลาดที่เฉพาะเจาะจงสำหรับงานนั้นๆ

ตัดสินใจว่าคุณจำเป็นต้องใช้องค์ประกอบที่กำหนดเองหรือไม่

ใช้องค์ประกอบที่กำหนดเองเฉพาะเมื่อคุณต้องการลักษณะการทำงานที่รวมไว้ วงจร หรือ API ที่สนับสนุน JS ที่นำกลับมาใช้ใหม่ได้ในแท็ก อย่าสร้างทักษะในกรณีต่อไปนี้

  • องค์ประกอบ HTML ธรรมดาที่มี CSS ก็เพียงพอแล้ว <button> หรือ <details> ที่มีสไตล์จะเข้าถึงได้ง่ายกว่าและมีค่าใช้จ่ายน้อยกว่าการติดตั้งใช้งานใหม่
  • สิ่งนี้เป็นเพียงการนำเสนอเท่านั้น โดยไม่มีลักษณะการทำงานใดๆ คลาสในองค์ประกอบแบบเนทีฟมีประสิทธิภาพมากกว่า และกำหนดขอบเขตได้ด้วย @layer หรือ @scope
  • คุณต้องการเพียงการกำหนดขอบเขตสไตล์บนเซิร์ฟเวอร์โดยไม่มีการโต้ตอบ สไตล์ชีตที่กำหนดขอบเขตหรือ Declarative Shadow DOM (โดยไม่มีการอัปเกรด) อาจเพียงพอแล้ว

การสร้างความหมายแบบเนทีฟขึ้นมาใหม่ (<my-button> ที่กำหนดเองซึ่งสร้างโฟกัส การเปิดใช้งาน และ ARIA ขึ้นมาใหม่) เป็นการใช้ในทางที่ผิดที่พบบ่อยที่สุด คุณจะรับช่วงการช่วยเหลือพิเศษของแพลตฟอร์มได้โดยไม่มีค่าใช้จ่ายก็ต่อเมื่อคุณนำองค์ประกอบแบบเนทีฟมาใช้ซ้ำเท่านั้น เมื่อ Wrapper สไตล์ <my-button> ได้รับการรับประกัน ซึ่งโดยปกติแล้วจะเป็นฮุกการจัดสไตล์ที่ใช้ร่วมกัน มาร์กอัปเพิ่มเติม หรือลักษณะการทำงานที่องค์ประกอบแบบเนทีฟแสดงไม่ได้ ให้รวม <button> จริงแทนที่จะนำไปใช้ใหม่ (ดูการจัดสไตล์คอมโพเนนต์เว็บสำหรับการส่งต่อสไตล์ไปยังองค์ประกอบแบบเนทีฟภายใน)

การทดสอบคือคุณต้องการสถานะที่ห่อหุ้ม, API ที่เขียนสคริปต์ได้ หรือลักษณะการทำงานที่องค์ประกอบเนทีฟแสดงไม่ได้หรือไม่ ไม่ใช่แค่รูปลักษณ์ที่แตกต่างกัน ปุ่มเปิด/ปิดการกดชอบ/รายการโปรดมีคุณสมบัติตรงตามเกณฑ์ โดยจะเก็บสถานะโดเมนที่เชื่อมโยงไว้ แสดงสถานะดังกล่าวเป็นฮุกการจัดรูปแบบสำหรับหน้าเว็บโดยรอบ และส่งเหตุการณ์ change ของตัวเอง ซึ่ง <button> ที่จัดรูปแบบแล้วไม่มีให้ ปุ่มที่เปลี่ยนสีเมื่อกดเท่านั้นจะไม่เปลี่ยนสี ให้ใช้ <button> + CSS เมื่อสร้าง ให้จำลองสถานะด้วยสถานะหรือแอตทริบิวต์ที่กำหนดเองตามความเหมาะสม (ดูองค์ประกอบที่กำหนดเอง)

จับคู่เครื่องมือกับฐานของโค้ด

การที่บางสิ่งควรเป็นองค์ประกอบที่กำหนดเองหรือไม่นั้นขึ้นอยู่กับสิ่งที่โปรเจ็กต์ใช้อยู่แล้ว เอเจนต์มักจะสรุปมากเกินไปและพยายามเข้าถึงองค์ประกอบใหม่มากเกินไป เมื่อมีข้อสงสัย ตัวเลือกที่เบากว่า (องค์ประกอบเนทีฟ, CSS, เทมเพลตเซิร์ฟเวอร์) มักจะถูกต้อง และคุณสามารถโปรโมตเป็นองค์ประกอบที่กำหนดเองในภายหลังได้หากการนำกลับมาใช้ใหม่หรือลักษณะการทำงานต้องการจริงๆ การคาดคะเนตามลำดับความสำคัญคร่าวๆ มีดังนี้

  • ฐานของโค้ดมีโมเดลคอมโพเนนต์ (React, Vue, Svelte, …) อยู่แล้ว ให้ใช้คอมโพเนนต์ของเฟรมเวิร์กนั้นเป็นค่าเริ่มต้นสำหรับ UI ในแอป ใช้องค์ประกอบที่กำหนดเองเฉพาะเมื่อสิ่งนั้นต้องหลุดออกจากเฟรมเวิร์กหรือมีอายุการใช้งานนานกว่าเฟรมเวิร์ก เช่น องค์ประกอบพื้นฐานของระบบการออกแบบที่แชร์ในแอปหรือเฟรมเวิร์กต่างๆ วิดเจ็ตที่วางลงในมาร์กอัปที่เฟรมเวิร์กไม่ได้ควบคุม หรือเอาต์พุตที่ต้องทำงานเป็น HTML ธรรมดา (อีเมล, CMS, ส่วนย่อย SSR) อย่าสร้างระบบคอมโพเนนต์แบบขนานสำหรับข้อมูลพร็อพเพอร์ตี้แอปทั่วไป
  • ไม่มีเครื่องมือ ส่วนใหญ่เป็นมาร์กอัปแบบคงที่ ใช้ HTML + CSS ธรรมดา หรือเทมเพลต/บางส่วนของเซิร์ฟเวอร์ องค์ประกอบที่กำหนดเองจะคุ้มค่าก็ต่อเมื่อคุณต้องการพฤติกรรม, วงจร หรือ API ที่สนับสนุน JS ในแท็กจริงๆ ไม่ใช่เพียงเพื่อแชร์มาร์กอัป ซึ่งเซิร์ฟเวอร์รวมหรือ <template> ทำได้โดยไม่ต้องส่ง JS ใดๆ
  • เครื่องมือสร้างเว็บไซต์แบบคงที่ซึ่งมีเกาะแห่งการโต้ตอบ แสดงผลมาร์กอัปแบบคงที่ และสงวนองค์ประกอบที่กำหนดเองไว้สำหรับส่วนที่มีการโต้ตอบ สำหรับ "มาร์กอัปจำนวนมากที่มีการโต้ตอบเพียงเล็กน้อย" ให้เก็บมาร์กอัปไว้ใน Light DOM (หรือ Declarative Shadow DOM) และปล่อยให้องค์ประกอบที่กำหนดเองขนาดเล็กปรับปรุงมาร์กอัปอย่างต่อเนื่อง แทนที่จะแสดงผลทุกอย่างจาก JS อีกครั้ง
  • คุณสามารถผลักดันองค์ประกอบที่มีอยู่แล้วให้ดียิ่งขึ้นแทนได้ การใช้องค์ประกอบแบบเนทีฟให้มากที่สุด (CSS, Listener บางรายการ, องค์ประกอบจำลองเป็นครั้งคราว) มักจะดีกว่าองค์ประกอบที่กำหนดเอง เนื่องจากคุณจะคงการช่วยเหลือพิเศษและลักษณะการทำงานของแพลตฟอร์มไว้ได้โดยไม่มีค่าใช้จ่าย เปลี่ยนไปใช้องค์ประกอบที่กำหนดเองเมื่อวิธีแก้ปัญหาชั่วคราวไม่สามารถดูแลรักษาได้อีกต่อไป เช่น เมื่อคุณต้องต่อสู้กับลักษณะการทำงานในตัวขององค์ประกอบ หรือประสบการณ์การเขียนแย่กว่า API คอมโพเนนต์ที่สะอาด การที่ต้องใช้ JS เล็กน้อยในองค์ประกอบในตัวไม่ได้เป็นเหตุผลในการแทนที่องค์ประกอบนั้น

กฎที่ใช้ร่วมกัน

โดยหลักการเหล่านี้มีผลกับคำแนะนำทั้งหมดด้านล่าง

  • บังคับ: ชื่อแท็กต้องเป็น kebab-case ที่มีขีดกลางอย่างน้อย 1 ขีด (เช่น my-element) ซึ่งจะช่วยแยกองค์ประกอบที่กำหนดเองออกจากองค์ประกอบในตัวทั้งในปัจจุบันและอนาคต
  • บังคับ: เรียก super() ก่อนใน Constructor ก่อนที่จะแตะ this การเรียกหลังจากคำสั่งใดๆ ที่อ่านหรือเขียน this จะแสดงข้อผิดพลาด
  • บังคับ: ใช้องค์ประกอบเชิงความหมาย (<button>, <nav>, <ul>) ภายในเทมเพลตเงา ความล้มเหลวด้านการช่วยเหลือพิเศษส่วนใหญ่ใน Shadow Tree มาจากมาร์กอัปที่ไม่ใช่เชิงความหมาย ช่องไม่ได้เปลี่ยนบทบาทของสิ่งที่ฉาย
  • บังคับ: การอ้างอิง ARIA id (aria-labelledby, aria-describedby, aria-controls) ไม่สามารถข้ามขอบเขต Shadow ได้ องค์ประกอบที่อ้างอิงและ id ที่ชี้ไปต้องอยู่ในแผนผังเดียวกัน
  • แนะนำให้ใช้ attachShadow({ mode: 'open' }) เพื่อให้เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ สคริปต์หน้าเว็บ และการไฮเดรตเซิร์ฟเวอร์เข้าถึง element.shadowRoot ได้ ใช้ 'closed' เฉพาะเมื่อคุณต้องซ่อนโครงสร้างภายในจากสคริปต์หน้าเว็บ
  • หลีกเลี่ยงองค์ประกอบในตัวที่กำหนดเอง (extends HTMLButtonElement ที่มี is="…") เนื่องจาก Safari ปฏิเสธที่จะจัดส่งองค์ประกอบดังกล่าวอย่างถาวร

เมทริกซ์คู่มือกรณีการใช้งาน

ระบุงานและดึงข้อมูลคู่มือของงานนั้นๆ โดยทำดังนี้

หากต้องการ… ดึงข้อมูล
กำหนดแท็กเชิงความหมายใหม่พร้อมลักษณะการทำงานและวงจร องค์ประกอบที่กำหนดเอง
กำหนดขอบเขตสไตล์และมาร์กอัปให้กับคอมโพเนนต์ และฉายเนื้อหาของผู้บริโภคลงในคอมโพเนนต์ Shadow DOM, เทมเพลต และสล็อต
แสดงผล Shadow Tree ของคอมโพเนนต์บนเซิร์ฟเวอร์ (SSR) โดยไม่มีเนื้อหาที่ไม่มีการจัดรูปแบบปรากฏขึ้นมาแวบหนึ่ง การแสดงผลองค์ประกอบที่กำหนดเองล่วงหน้า
จัดรูปแบบข้ามขอบเขต Shadow (การกำหนดธีม, ::part, คุณสมบัติที่กำหนดเอง) การจัดรูปแบบคอมโพเนนต์เว็บ
ส่งค่าของตัวควบคุมที่กำหนดเองไปยัง <form> โดยรอบ องค์ประกอบที่กำหนดเองที่เชื่อมโยงกับแบบฟอร์ม
ทำให้องค์ประกอบที่กำหนดเองเข้าถึงได้ (บทบาท, โฟกัส, ARIA ใน Shadow Root) คอมโพเนนต์เว็บที่เข้าถึงได้