เราสร้างส่วนประกอบ UI ใน Rails ได้อย่างไร
เผยแพร่แล้ว: 2024-06-28การรักษาความสอดคล้องของภาพในเว็บแอปพลิเคชันขนาดใหญ่เป็นปัญหาร่วมกันในหลายๆ องค์กร เว็บแอปพลิเคชันหลักที่อยู่เบื้องหลังผลิตภัณฑ์ Flywheel ของเราสร้างขึ้นด้วย Ruby on Rails และเรามีนักพัฒนา Rails หลายคนและนักพัฒนาส่วนหน้าสามคนที่เขียนโค้ดในแต่ละวัน เราให้ความสำคัญกับการออกแบบเช่นกัน (ซึ่งเป็นหนึ่งในค่านิยมหลักของเราในฐานะบริษัท) และมีนักออกแบบสามคนที่ทำงานอย่างใกล้ชิดกับนักพัฒนาในทีม Scrum ของเรา
เป้าหมายหลักของเราคือเพื่อให้แน่ใจว่านักพัฒนาซอฟต์แวร์ทุกคนสามารถสร้างเพจแบบตอบสนองโดยไม่มีอุปสรรคใดๆ โดยทั่วไปอุปสรรคต่างๆ ได้แก่ การไม่รู้ว่าส่วนประกอบใดที่มีอยู่แล้วที่จะใช้สร้างแบบจำลอง (ซึ่งนำไปสู่การขยายฐานโค้ดด้วยส่วนประกอบที่คล้ายกันและซ้ำซ้อนมาก) และไม่รู้ว่าเมื่อใดควรหารือเกี่ยวกับการนำกลับมาใช้ใหม่กับนักออกแบบ สิ่งนี้มีส่วนทำให้เกิดประสบการณ์ของลูกค้าที่ไม่สอดคล้องกัน ความหงุดหงิดของนักพัฒนา และภาษาการออกแบบที่แตกต่างกันระหว่างนักพัฒนาและนักออกแบบ
เราได้ผ่านการทำซ้ำคำแนะนำสไตล์และวิธีการสร้าง/บำรุงรักษารูปแบบ UI และส่วนประกอบต่างๆ และการวนซ้ำแต่ละครั้งช่วยแก้ปัญหาที่เราเผชิญอยู่ในขณะนั้น เรามั่นใจว่าแนวทางใหม่ของเราจะเตรียมเราให้พร้อมไปอีกนาน หากคุณประสบปัญหาที่คล้ายกันในแอปพลิเคชัน Rails ของคุณและต้องการเข้าถึงส่วนประกอบต่างๆ จากฝั่งเซิร์ฟเวอร์ ฉันหวังว่าบทความนี้จะให้แนวคิดแก่คุณได้
ในบทความนี้ ฉันจะเจาะลึกเกี่ยวกับ:
- เรากำลังแก้ไขเพื่ออะไร
- การจำกัดส่วนประกอบ
- การแสดงผลส่วนประกอบทางฝั่งเซิร์ฟเวอร์
- โดยที่เราไม่สามารถใช้ส่วนประกอบฝั่งเซิร์ฟเวอร์ได้
เรากำลังแก้ไขเพื่ออะไร
เราต้องการจำกัดองค์ประกอบ UI ของเราอย่างสมบูรณ์ และลดความเป็นไปได้ที่ UI เดียวกันจะถูกสร้างขึ้นมากกว่าหนึ่งวิธี แม้ว่าลูกค้าอาจไม่สามารถบอกได้ (ในตอนแรก) การไม่มีข้อจำกัดในส่วนประกอบทำให้เกิดประสบการณ์ที่สับสนของนักพัฒนา ทำให้สิ่งต่าง ๆ ยากมากที่จะรักษา และทำให้ยากต่อการเปลี่ยนแปลงการออกแบบทั่วโลก
วิธีดั้งเดิมที่เราเข้าถึงส่วนประกอบต่างๆ คือการใช้คู่มือสไตล์ของเรา ซึ่งระบุมาร์กอัปทั้งหมดที่จำเป็นในการสร้างส่วนประกอบที่กำหนด ตัวอย่างเช่น หน้าคำแนะนำสไตล์สำหรับส่วนประกอบ Slat ของเรามีลักษณะดังนี้:
วิธีนี้ใช้ได้ผลดีเป็นเวลาหลายปี แต่ปัญหาเริ่มคืบคลานเมื่อเราเพิ่มตัวแปร สถานะ หรือวิธีอื่นในการใช้ส่วนประกอบ ด้วย UI ที่ซับซ้อน การอ้างอิงคำแนะนำสไตล์จึงกลายเป็นเรื่องยุ่งยากเพื่อทราบว่าควรใช้คลาสใดและควรหลีกเลี่ยงคลาสใด และมาร์กอัปลำดับใดที่จำเป็นในการแสดงผลรูปแบบที่ต้องการ
บ่อยครั้ง นักออกแบบจะทำการเพิ่มเติมหรือปรับแต่งองค์ประกอบที่กำหนดเล็กน้อย เนื่องจากคู่มือสไตล์ไม่ค่อยสนับสนุนสิ่งนั้น การแฮ็กทางเลือกอื่นเพื่อให้ปรับแต่งให้แสดงได้อย่างถูกต้อง (เช่น การแบ่งส่วนอื่นของส่วนประกอบอื่นอย่างไม่เหมาะสม) จึงกลายเป็นเรื่องปกติที่น่ารำคาญ
ตัวอย่างส่วนประกอบที่ไม่มีข้อจำกัด
เพื่อแสดงให้เห็นว่าความไม่สอดคล้องกันเกิดขึ้นได้อย่างไรเมื่อเวลาผ่านไป ฉันจะใช้ตัวอย่างที่เรียบง่าย (และสร้างสรรค์ขึ้นมา) แต่พบได้บ่อยมากของหนึ่งในส่วนประกอบของเราในแอป Flywheel: ส่วนหัวของการ์ด
เริ่มต้นใหม่จากการออกแบบจำลอง นี่คือลักษณะของส่วนหัวของการ์ด มันค่อนข้างเรียบง่ายด้วยชื่อเรื่อง ปุ่ม และเส้นขอบด้านล่าง
.card__ส่วนหัว .card__header-ซ้าย %h2 การสำรองข้อมูล .card__header-ขวา = link_to "#" ทำ = ไอคอน ("plus_small")
หลังจากที่เขียนโค้ดแล้ว ลองจินตนาการถึงนักออกแบบที่ต้องการเพิ่มไอคอนทางด้านซ้ายของชื่อ เมื่อแกะกล่องแล้ว จะไม่มีระยะขอบระหว่างไอคอนและชื่อเรื่อง
- .card__header-ซ้าย = ไอคอน ("arrow_backup", สี: "gray25") %h2 การสำรองข้อมูล -
ตามหลักการแล้ว เราจะแก้ปัญหานั้นใน CSS สำหรับส่วนหัวของการ์ด แต่สำหรับตัวอย่างนี้ สมมติว่านักพัฒนาคนอื่นคิดว่า "โอ้ ฉันรู้! เรามีตัวช่วยมาร์จิ้น ฉันจะตบคลาสผู้ช่วยตามชื่อ”
- .card__header-ซ้าย = ไอคอน ("arrow_backup", สี: "gray25") %h2.--ml-10 การสำรองข้อมูล -
ในทางเทคนิค แล้วดูเหมือนว่าการเยาะเย้ยทำใช่ไหม! แน่นอน แต่สมมุติว่าหนึ่งเดือนต่อมา นักพัฒนา รายอื่น ต้องการส่วนหัวของการ์ด แต่ไม่มีไอคอน พวกเขาค้นหาตัวอย่างสุดท้าย คัดลอก/วาง และลบไอคอนออก
มันดูถูกต้องอีกครั้งใช่ไหม? สำหรับคนที่ไม่มีความเข้าใจเรื่องการออกแบบ นอกบริบทแน่นอน! แต่ดูข้างๆต้นฉบับสิ ขอบซ้ายของชื่อยังคงอยู่ที่นั่นเพราะพวกเขาไม่รู้ว่าจำเป็นต้องลบตัวช่วยที่เหลือของขอบออก!
ยกตัวอย่างนี้ไปอีกขั้น สมมติว่าจำลองอีกอันเรียกส่วนหัวของการ์ดที่ไม่มีขอบด้านล่าง อาจพบสถานะที่เรามีในคู่มือสไตล์ที่เรียกว่า "ไร้ขอบ" และนำไปใช้ สมบูรณ์แบบ!
นักพัฒนารายอื่นอาจพยายามใช้โค้ดนั้นซ้ำ แต่ในกรณีนี้ พวกเขาจำเป็นต้องมีเส้นขอบจริงๆ สมมติว่าพวกเขาเพิกเฉยต่อการใช้งานที่เหมาะสมที่บันทึกไว้ในคู่มือสไตล์ และไม่ทราบว่าการลบคลาสไร้ขอบจะทำให้พวกเขามีขอบเขต แต่จะเพิ่มกฎแนวนอนแทน ในที่สุดก็มีช่องว่างภายในเพิ่มเติมระหว่างชื่อเรื่องและเส้นขอบ ดังนั้นพวกเขาจึงใช้คลาสตัวช่วยกับ hr และ voila!
ด้วยการปรับเปลี่ยนส่วนหัวของการ์ดแบบเดิมทั้งหมด ตอนนี้เรามีปัญหาเรื่องโค้ด
.card__header.--ไร้ขอบ .card__header-ซ้าย %h2.--ml-10 การสำรองข้อมูล .card__header-ขวา = link_to "#" ทำ = ไอคอน ("plus_small") %ชม.--mt-0.--mb-0
โปรดทราบว่าตัวอย่างข้างต้นเป็นเพียงการแสดงให้เห็นว่าส่วนประกอบที่ไม่มีข้อจำกัดสามารถเลอะเทอะเมื่อเวลาผ่านไปได้อย่างไร หากใครในทีมของเราพยายามจัดส่งส่วนหัวของการ์ดรูปแบบต่างๆ ก็ ควร จะตรวจสอบได้ด้วยการตรวจสอบการออกแบบหรือการตรวจสอบโค้ด แต่ของแบบนี้บางครั้งอาจหลุดรอดมาได้ ดังนั้นเราจึงจำเป็นต้องกันกระสุน!
ส่วนประกอบที่จำกัด
คุณอาจคิดว่าปัญหาที่ระบุไว้ข้างต้นได้รับการแก้ไขแล้วด้วยส่วนประกอบต่างๆ อย่างชัดเจน นั่นเป็นสมมติฐานที่ถูกต้อง! เฟรมเวิร์กส่วนหน้าเช่น React และ Vue ได้รับความนิยมอย่างมากสำหรับจุดประสงค์นี้ มันเป็นเครื่องมือที่น่าทึ่งสำหรับการห่อหุ้ม UI อย่างไรก็ตาม มีปัญหาอย่างหนึ่งที่เราไม่ชอบเสมอไป เนื่องจากพวกเขาต้องการให้ JavaScript แสดงผล UI ของคุณ
แอปพลิเคชัน Flywheel ของเรามีแบ็คเอนด์ที่หนักมาก โดยมี HTML ที่เรนเดอร์จากเซิร์ฟเวอร์เป็นหลัก แต่โชคดีสำหรับเราที่ส่วนประกอบต่างๆ มีได้หลายรูปแบบ ในตอนท้ายของวัน ส่วนประกอบ UI คือการสรุปสไตล์และกฎการออกแบบที่ส่งออกมาร์กอัปไปยังเบราว์เซอร์ ด้วยการตระหนักรู้นี้ เราสามารถใช้แนวทางเดียวกันนี้กับส่วนประกอบต่างๆ ได้ แต่ไม่มีค่าใช้จ่ายในกรอบงาน JavaScript
เราจะมาดูวิธีที่เราสร้างส่วนประกอบที่มีข้อจำกัดด้านล่าง แต่ต่อไปนี้คือประโยชน์บางประการที่เราพบจากการใช้ส่วนประกอบเหล่านี้:
- ไม่มีวิธีที่ผิดในการรวบรวมส่วนประกอบเข้าด้วยกัน
- ส่วนประกอบจะเป็นผู้คิดการออกแบบทั้งหมดให้กับคุณ (คุณเพียงแค่ผ่านตัวเลือก!)
- ไวยากรณ์สำหรับการสร้างส่วนประกอบมีความสอดคล้องและง่ายต่อการให้เหตุผล
- หากจำเป็นต้องเปลี่ยนแปลงการออกแบบในส่วนประกอบ เราสามารถเปลี่ยนได้ครั้งเดียวในส่วนประกอบและมั่นใจได้ว่าได้รับการอัปเดตทุกที่
การแสดงผลส่วนประกอบทางฝั่งเซิร์ฟเวอร์
แล้วเรากำลังพูดถึงอะไรโดยการจำกัดส่วนประกอบ? มาเจาะลึกกันดีกว่า!
ตามที่กล่าวไว้ข้างต้น เราต้องการให้นักพัฒนาที่ทำงานในแอปพลิเคชันสามารถดูการจำลองการออกแบบของหน้าและสามารถสร้างหน้านั้นได้ทันทีโดยไม่มีอุปสรรค นั่นหมายความว่าวิธีการสร้าง UI จะต้อง A) ได้รับการจัดทำเป็นเอกสารไว้เป็นอย่างดี และ B) มีความชัดเจนและไม่มีการคาดเดา
บางส่วนเพื่อช่วยเหลือ (หรืออย่างที่เราคิด)
สิ่งแรกที่เราเคยลองในเรื่องนี้ในอดีตคือการใช้ Rails บางส่วน บางส่วนเป็นเครื่องมือเดียวที่ Rails ให้คุณนำมาใช้ซ้ำในเทมเพลตได้ โดยปกติแล้ว พวกเขาคือสิ่งแรกที่ทุกคนเข้าถึง แต่มีข้อเสียเปรียบที่สำคัญที่ต้องพึ่งพาสิ่งเหล่านี้ เนื่องจากหากคุณต้องการรวมตรรกะเข้ากับเทมเพลตที่นำมาใช้ซ้ำได้ คุณมีสองทางเลือก: ทำซ้ำตรรกะกับตัวควบคุมทุกตัวที่ใช้ตรรกะบางส่วนหรือฝังตรรกะลงในบางส่วนเอง
บางส่วนจะป้องกันข้อผิดพลาดในการคัดลอก/วางซ้ำ และทำงานได้ดีในสองสามครั้งแรกที่คุณต้องใช้บางสิ่งซ้ำ แต่จากประสบการณ์ของเรา ในไม่ช้า บางส่วนจะเต็มไปด้วยการรองรับฟังก์ชันและตรรกะที่มากขึ้นเรื่อยๆ แต่ตรรกะไม่ควรอยู่ในเทมเพลต!
ความรู้เบื้องต้นเกี่ยวกับเซลล์
โชคดีที่มีทางเลือกอื่นที่ดีกว่าสำหรับ Partials ซึ่งช่วยให้เราใช้โค้ดซ้ำ และ เก็บตรรกะไว้ไม่ให้มองข้าม มันถูกเรียกว่า Cells ซึ่งเป็นอัญมณี Ruby ที่พัฒนาโดย Trailblazer เซลล์มีมานานแล้วก่อนที่เฟรมเวิร์กส่วนหน้าเช่น React และ Vue จะได้รับความนิยมเพิ่มขึ้น และเซลล์เหล่านี้ช่วยให้คุณสามารถเขียนโมเดลมุมมองแบบห่อหุ้มที่จัดการทั้งตรรกะ และ เทมเพลตได้ พวกเขาให้มุมมองที่เป็นนามธรรมซึ่ง Rails ไม่ได้มีไว้นอกกรอบจริงๆ จริงๆ แล้ว เราใช้ Cells ในแอป Flywheel มาระยะหนึ่งแล้ว เพียงแต่ไม่ใช่ในระดับสากลที่สามารถนำกลับมาใช้ใหม่ได้เป็นพิเศษ
ในระดับที่ง่ายที่สุด Cells ช่วยให้เราสามารถสรุปมาร์กอัปบางส่วนได้เช่นนี้ (เราใช้ Haml สำหรับภาษาเทมเพลตของเรา):
%div %h1 สวัสดีชาวโลก!
เป็นรูปแบบมุมมองที่นำมาใช้ซ้ำได้ (คล้ายกับบางส่วนมาก ณ จุดนี้) และเปลี่ยนให้เป็นสิ่งนี้:
= เซลล์("hello_world")
ท้ายที่สุดแล้วสิ่งนี้ช่วยให้เราจำกัดส่วนประกอบให้ไม่สามารถเพิ่มคลาสตัวช่วยหรือส่วนประกอบย่อยที่ไม่ถูกต้องได้โดยไม่ต้องแก้ไขเซลล์เอง
การสร้างเซลล์
เราใส่ UI Cells ทั้งหมดของเราไว้ในไดเร็กทอรี app/cells/ui แต่ละเซลล์จะต้องมีไฟล์ Ruby เพียงไฟล์เดียว ซึ่งต่อท้ายด้วย _cell.rb ในทางเทคนิคแล้ว คุณสามารถเขียนเทมเพลตใน Ruby ด้วยตัวช่วย content_tag ได้ แต่เซลล์ส่วนใหญ่ของเรายังมีเทมเพลต Haml ที่เกี่ยวข้องซึ่งอยู่ในโฟลเดอร์ที่ตั้งชื่อตามส่วนประกอบ
เซลล์พื้นฐานขั้นสูงที่ไม่มีตรรกะจะมีลักษณะดังนี้:
// เซลล์/ui/slat_cell.rb UI ของโมดูล คลาส SlatCell < ViewModel แน่นอนแสดง จบ จบ จบ
วิธีการแสดงคือสิ่งที่แสดงผลเมื่อคุณสร้างอินสแตนซ์ของเซลล์ และจะค้นหาไฟล์ show.haml ที่เกี่ยวข้องในโฟลเดอร์ที่มีชื่อเดียวกันกับเซลล์โดยอัตโนมัติ ในกรณีนี้คือ app/cells/ui/slat (เรากำหนดขอบเขต UI Cells ทั้งหมดของเราเป็นโมดูล UI)
ในเทมเพลต คุณสามารถเข้าถึงตัวเลือกที่ส่งผ่านไปยังเซลล์ได้ ตัวอย่างเช่น หากเซลล์ถูกสร้างอินสแตนซ์ในมุมมอง = cell("ui/slat", title: "Title", subtitle: "Subtitle", label: "Label") เราสามารถเข้าถึงตัวเลือกเหล่านั้นผ่านออบเจ็กต์ตัวเลือก
// เซลล์/ui/slat/show.haml .ไม้ระแนง .slat__inner .slat__เนื้อหา %h4= ตัวเลือก[:หัวข้อ] %p= ตัวเลือก[:คำบรรยาย] = ไอคอน(ตัวเลือก[:ไอคอน], สี: "สีน้ำเงิน")
หลายครั้งเราจะย้ายองค์ประกอบแบบง่ายและค่าขององค์ประกอบเหล่านั้นไปไว้ในวิธีการในเซลล์ เพื่อป้องกันไม่ให้องค์ประกอบว่างถูกเรนเดอร์หากไม่มีตัวเลือก
// เซลล์/ui/slat_cell.rb ชื่อแน่นอน กลับยกเว้นตัวเลือก [:title] content_tag :h4, ตัวเลือก[:ชื่อ] จบ คำบรรยายแน่นอน กลับยกเว้นตัวเลือก [: คำบรรยาย] content_tag :p, ตัวเลือก[:คำบรรยาย] จบ
// เซลล์/ui/slat/show.haml .ไม้ระแนง .slat__inner .slat__เนื้อหา = ชื่อเรื่อง = คำบรรยาย
การรวมเซลล์ด้วยยูทิลิตี้ UI
หลังจากพิสูจน์แนวคิดที่ว่าสิ่งนี้สามารถทำงานได้ในวงกว้าง ฉันต้องการจัดการกับมาร์กอัปภายนอกที่จำเป็นในการเรียกเซลล์ มันไม่ค่อยลื่นไหลนักและยากที่จะจดจำ เราเลยจัดตัวช่วยเล็กๆ น้อยๆ มาให้! ตอนนี้เราสามารถโทร = ui “name_of_component” และส่งผ่านตัวเลือกแบบอินไลน์ได้
= ui "slat", ชื่อเรื่อง: "ชื่อเรื่อง", คำบรรยาย: "คำบรรยาย", ป้ายกำกับ: "ป้ายกำกับ"
การส่งผ่านตัวเลือกเป็นบล็อกแทนที่จะเป็นแบบอินไลน์
หากใช้ยูทิลิตี้ UI เพิ่มเติมอีกเล็กน้อย ก็เห็นได้ชัดว่าเซลล์ที่มีตัวเลือกมากมายในบรรทัดเดียวนั้นยากที่จะติดตามและน่าเกลียดมาก นี่คือตัวอย่างของเซลล์ที่มีตัวเลือกมากมายที่กำหนดไว้ในบรรทัด:
= ui “slat”, หัวเรื่อง: “หัวเรื่อง”, คำบรรยาย: “คำบรรยาย”, ป้ายกำกับ: “ป้ายกำกับ”, ลิงก์: “#”, tertiary_title: “ตติยภูมิ”, ปิดการใช้งาน: จริง, รายการตรวจสอบ: [“รายการที่ 1”, “รายการ 2”, “รายการ 3”]
มันยุ่งยากมาก ซึ่งทำให้เราสร้างคลาสที่เรียกว่า OptionProxy ซึ่งจะดักจับเมธอด Cells setter และแปลเป็นค่าแฮช ซึ่งจากนั้นจะรวมเข้ากับตัวเลือกต่างๆ ถ้ามันฟังดูซับซ้อน ไม่ต้องกังวล มันก็ซับซ้อนสำหรับฉันเหมือนกัน นี่คือส่วนสำคัญของคลาส OptionProxy ที่ Adam หนึ่งในวิศวกรซอฟต์แวร์อาวุโสของเราเขียนไว้
นี่คือตัวอย่างการใช้คลาส OptionProxy ภายในเซลล์ของเรา:
UI ของโมดูล คลาส SlatCell < ViewModel แน่นอนแสดง OptionProxy.new(self).yield!(ตัวเลือก, &บล็อก) ซุปเปอร์() จบ จบ จบ
ในตอนนี้ เราสามารถเปลี่ยนตัวเลือกอินไลน์ที่ยุ่งยากของเราให้กลายเป็นบล็อกที่น่าพึงพอใจยิ่งขึ้นได้!
= ui "slat" ทำ |slat| - slat.title = "ชื่อเรื่อง" - slat.subtitle = "คำบรรยาย" - slat.label = "ป้ายกำกับ" - slat.link = "#" - slat.tertiary_title = "ตติยภูมิ" - slat.disabled = จริง - slat.checklist = ["รายการที่ 1", "รายการที่ 2", "รายการที่ 3"]
ขอแนะนำลอจิก
จนถึงจุดนี้ ตัวอย่างยังไม่ได้รวมตรรกะใดๆ เกี่ยวกับสิ่งที่มุมมองแสดง นั่นเป็นหนึ่งในสิ่งที่ดีที่สุดที่ Cells นำเสนอ ดังนั้นเรามาพูดถึงมันกันดีกว่า!
ด้วยการใช้องค์ประกอบ slat ของเรา บางครั้งเราจำเป็นต้องเรนเดอร์สิ่งทั้งหมดเป็นลิงก์ และบางครั้งก็เรนเดอร์เป็น div ขึ้นอยู่กับว่ามีตัวเลือกลิงก์อยู่หรือไม่ ฉันเชื่อว่านี่เป็นองค์ประกอบเดียวที่เรามีที่สามารถเรนเดอร์เป็น div หรือลิงก์ได้ แต่มันเป็นตัวอย่างที่ดีทีเดียวของพลังของเซลล์
วิธีการด้านล่างนี้จะเรียกตัวช่วย link_to หรือ content_tag ขึ้นอยู่กับตัวเลือก [:link]
def คอนเทนเนอร์ (&บล็อก) แท็ก = ถ้าตัวเลือก[:ลิงค์] [:link_to, ตัวเลือก[:ลิงก์]] อื่น [:content_tag, :div] จบ send(*แท็ก, คลาส: “slat__inner”, &บล็อก) สิ้นสุด
ซึ่งช่วยให้เราสามารถแทนที่องค์ประกอบ .slat__inner ในเทมเพลตด้วยบล็อกคอนเทนเนอร์:
.ไม้ระแนง = คอนเทนเนอร์ทำ -
อีกตัวอย่างหนึ่งของตรรกะใน Cells ที่เราใช้บ่อยก็คือคลาสเอาท์พุตแบบมีเงื่อนไข สมมติว่าเราเพิ่มตัวเลือกที่ปิดใช้งานลงในเซลล์ ไม่มีสิ่งอื่นใดในการเรียกใช้เซลล์ที่เปลี่ยนแปลง นอกจากตอนนี้คุณสามารถผ่านตัวเลือกที่ปิดใช้งาน: จริง และดูว่าสิ่งทั้งหมดกลายเป็นสถานะปิดใช้งาน (เป็นสีเทาพร้อมกับลิงก์ที่ไม่สามารถคลิกได้)
= ui "slat" ทำ |slat| - - slat.disabled = จริง
เมื่อตัวเลือกที่ปิดใช้งานเป็นจริง เราสามารถตั้งค่าคลาสให้กับองค์ประกอบในเทมเพลตที่จำเป็นเพื่อให้ได้รูปลักษณ์ที่ปิดใช้งานตามที่ต้องการ
.slat { class: possible_classes("--disabled": options[:disabled]) } .slat__inner .slat__เนื้อหา %h4{ class: possible_classes("--alt": options[:disabled]) }= ตัวเลือก[:ชื่อ] %p{ คลาส: possible_classes("--alt": options[:disabled]) }= ตัวเลือก[:คำบรรยาย] = ไอคอน (ตัวเลือก [: ไอคอน], สี: "สีเทา")
ตามเนื้อผ้า เราจะต้องจำ (หรืออ้างอิงคำแนะนำสไตล์) ว่าองค์ประกอบใดจำเป็นต้องมีคลาสเพิ่มเติมเพื่อทำให้สิ่งทั้งหมดทำงานได้อย่างถูกต้องในสถานะปิดใช้งาน เซลล์ช่วยให้เราสามารถประกาศทางเลือกหนึ่งทางแล้วจึงทำการยกของหนักให้เรา
หมายเหตุ: possible_classes เป็นวิธีการที่เราสร้างขึ้นเพื่อให้สามารถใช้คลาสใน Haml แบบมีเงื่อนไขในลักษณะที่ดี
โดยที่เราไม่สามารถใช้ส่วนประกอบฝั่งเซิร์ฟเวอร์ได้
แม้ว่าแนวทางเซลล์จะมีประโยชน์อย่างมากสำหรับการใช้งานเฉพาะของเราและวิธีการทำงานของเรา แต่ฉันก็ไม่กล้าที่จะบอกว่าวิธีนี้สามารถแก้ไขปัญหาของเราได้ 100% เรายังคงเขียน JavaScript (จำนวนมาก) และสร้างประสบการณ์บางอย่างใน Vue ทั่วทั้งแอปของเรา 75% ของเวลาทั้งหมด เทมเพลต Vue ของเรายังคงอยู่ใน Haml และเราเชื่อมโยงอินสแตนซ์ Vue ของเรากับองค์ประกอบที่มีอยู่ ซึ่งช่วยให้เรายังคงใช้ประโยชน์จากแนวทางเซลล์ได้
อย่างไรก็ตาม ในสถานที่ที่เหมาะสมกว่าที่จะจำกัดส่วนประกอบอย่างสมบูรณ์ให้เป็นอินสแตนซ์ Vue ไฟล์เดียว เราจะไม่สามารถใช้ Cells ได้ ตัวอย่างเช่น รายการที่เราเลือกคือ Vue ทั้งหมด แต่ฉันคิดว่าไม่เป็นไร! เราไม่พบความจำเป็นที่จะต้องมีส่วนประกอบเวอร์ชันที่ซ้ำกันทั้งในส่วนประกอบ Cells และ Vue ดังนั้นจึงเป็นเรื่องปกติที่ส่วนประกอบบางส่วนสร้างขึ้นด้วย Vue 100% และบางส่วนก็สร้างด้วย Cells
หากส่วนประกอบถูกสร้างขึ้นด้วย Vue หมายความว่า JavaScript จำเป็นต้องสร้างส่วนประกอบนั้นใน DOM และเราใช้ประโยชน์จากเฟรมเวิร์ก Vue เพื่อดำเนินการดังกล่าว สำหรับส่วนประกอบอื่นๆ ส่วนใหญ่ของเรา พวกมันไม่จำเป็นต้องใช้ JavaScript และหากจำเป็นต้องใช้ พวกมันต้องการให้สร้าง DOM ไว้แล้ว และเราเพียงแค่เชื่อมต่อและเพิ่ม Listener เหตุการณ์
ในขณะที่เราพัฒนาแนวทางเซลล์ไปเรื่อย ๆ เราจะทดลองการผสมผสานระหว่างส่วนประกอบของเซลล์และส่วนประกอบ Vue เพื่อให้เรามีวิธีเดียวในการสร้างและใช้ส่วนประกอบต่างๆ ฉันยังไม่รู้ว่ามันเป็นยังไง พอไปถึงแล้วเราจะข้ามสะพานนั้น!
บทสรุปของเรา
จนถึงตอนนี้เราได้แปลงองค์ประกอบภาพที่ใช้บ่อยที่สุดประมาณสามสิบรายการเป็นเซลล์แล้ว มันทำให้เรามีประสิทธิผลเพิ่มขึ้นอย่างมาก และทำให้นักพัฒนาสามารถตรวจสอบได้ว่าประสบการณ์ที่พวกเขากำลังสร้างนั้นถูกต้องและไม่ถูกแฮ็กด้วยกัน
ทีมออกแบบของเรามั่นใจมากขึ้นกว่าที่เคยว่าส่วนประกอบและประสบการณ์ในแอปของเราเป็นแบบ 1:1 เมื่อเทียบกับสิ่งที่พวกเขาออกแบบใน Adobe XD ขณะนี้การเปลี่ยนแปลงหรือการเพิ่มเติมส่วนประกอบได้รับการจัดการผ่านการโต้ตอบกับนักออกแบบและนักพัฒนาส่วนหน้าเท่านั้น ซึ่งช่วยให้ทีมที่เหลือมีสมาธิและไม่ต้องกังวลในการรู้วิธีปรับแต่งส่วนประกอบให้ตรงกับการจำลองการออกแบบ
เรากำลังทำซ้ำแนวทางของเราในการจำกัดส่วนประกอบ UI อย่างต่อเนื่อง แต่ฉันหวังว่าเทคนิคที่แสดงในบทความนี้จะช่วยให้คุณพอเห็นได้ว่าอะไรใช้ได้ผลดีสำหรับเรา!
มาร่วมงานกับเรา!
แต่ละแผนกที่ทำงานเกี่ยวกับผลิตภัณฑ์ของเรามีผลกระทบอย่างมีนัยสำคัญต่อลูกค้าและผลกำไรของเรา ไม่ว่าจะเป็นการสนับสนุนลูกค้า การพัฒนาซอฟต์แวร์ การตลาด หรืออะไรก็ตาม เราทุกคนทำงานร่วมกันเพื่อบรรลุภารกิจของเราในการสร้างบริษัทโฮสติ้งที่ผู้คนสามารถตกหลุมรักได้อย่างแท้จริง
พร้อมที่จะเข้าร่วมทีมของเราแล้วหรือยัง? เรากำลังจ้าง! สมัครที่นี่