เราสร้างส่วนประกอบ UI ใน Rails ที่ Flywheel ได้อย่างไร

เผยแพร่แล้ว: 2019-11-16

การรักษาความสอดคล้องของภาพในเว็บแอปพลิเคชันขนาดใหญ่เป็นปัญหาร่วมกันทั่วทั้งองค์กร ที่ Flywheel เราไม่ต่างกัน เว็บแอปพลิเคชันหลักของเราสร้างขึ้นด้วย Ruby on Rails และเรามีนักพัฒนา Rails ประมาณ 15 รายและนักพัฒนาส่วนหน้าอีกสามคนที่มอบโค้ดให้กับมันในวันใดวันหนึ่ง เราให้ความสำคัญกับการออกแบบเช่นกัน (เป็นหนึ่งในค่านิยมหลักของเราในฐานะบริษัท) และมีนักออกแบบสามคนที่ทำงานอย่างใกล้ชิดกับนักพัฒนาในทีม Scrum ของเรา

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

เราได้ผ่านการทำซ้ำหลายครั้งของคำแนะนำสไตล์และวิธีการในการสร้าง/รักษารูปแบบและส่วนประกอบ UI และการทำซ้ำแต่ละครั้งช่วยแก้ปัญหาที่เราเผชิญอยู่ในขณะนั้น ตอนนี้เรากำลังเข้าสู่แนวทางใหม่ (สำหรับเรา) ที่ฉันมั่นใจว่าจะเตรียมเราให้พร้อมไปอีกนาน หากคุณประสบปัญหาที่คล้ายกันในแอปพลิเคชัน Rails ของคุณและคุณต้องการเข้าถึงส่วนประกอบจากฝั่งเซิร์ฟเวอร์ ฉันหวังว่าบทความนี้จะสามารถให้แนวคิดบางอย่างแก่คุณได้

ในบทความนี้ฉันจะเจาะลึกไปที่:

  • เรากำลังแก้ปัญหาเพื่ออะไร
  • ส่วนประกอบที่มีข้อจำกัด
  • การแสดงผลส่วนประกอบทางฝั่งเซิร์ฟเวอร์
  • ที่เราไม่สามารถใช้ส่วนประกอบฝั่งเซิร์ฟเวอร์ได้


เรากำลังแก้ปัญหาเพื่ออะไร

เราต้องการจำกัดองค์ประกอบ UI ของเราโดยสมบูรณ์ และขจัดความเป็นไปได้ที่จะสร้าง UI เดียวกันได้มากกว่าหนึ่งวิธี แม้ว่าลูกค้าอาจไม่สามารถบอกได้ (ในตอนแรก) การไม่มีข้อจำกัดเกี่ยวกับส่วนประกอบทำให้เกิดประสบการณ์นักพัฒนาที่สับสน ทำให้รักษาสิ่งต่างๆ ได้ยาก และทำให้การเปลี่ยนแปลงการออกแบบทั่วโลกทำได้ยาก

วิธีดั้งเดิมที่เราเข้าถึงส่วนประกอบคือผ่านคู่มือสไตล์ของเรา ซึ่งระบุมาร์กอัปจำนวนมากที่จำเป็นในการสร้างส่วนประกอบที่กำหนด ตัวอย่างเช่น นี่คือสิ่งที่หน้าคำแนะนำรูปแบบสำหรับองค์ประกอบแผ่นระแนงของเรามีลักษณะดังนี้:

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

ตัวอย่างส่วนประกอบที่ไม่มีข้อจำกัด

เพื่อแสดงให้เห็นว่าความไม่สอดคล้องกันปรากฏอย่างไรเมื่อเวลาผ่านไป ฉันจะใช้ตัวอย่างที่เรียบง่าย (และมีการประดิษฐ์ขึ้น) แต่ที่พบบ่อยมากของหนึ่งในส่วนประกอบของเราในแอป Flywheel: ส่วนหัวของการ์ด

เริ่มต้นใหม่จากการจำลองการออกแบบ นี่คือลักษณะของส่วนหัวของการ์ด มันค่อนข้างเรียบง่ายด้วยชื่อ ปุ่ม และขอบด้านล่าง

.card__header
  .card__header-left
    %h2 Backups

  .card__header-right
    = link_to "#" do
      = icon("plus_small")

หลังจากที่เขียนโค้ดแล้ว ลองนึกภาพนักออกแบบที่ต้องการเพิ่มไอคอนทางด้านซ้ายของชื่อ เมื่อนำออกจากกล่อง จะไม่มีระยะขอบระหว่างไอคอนกับชื่อ

...
  .card__header-left
    = icon("arrow_backup", color: "gray25")
    %h2 Backups
...

เราจะแก้ปัญหานั้นใน CSS สำหรับส่วนหัวของการ์ด แต่สำหรับตัวอย่างนี้ นักพัฒนารายอื่นคิดว่า "โอ้ ฉันรู้! เรามีตัวช่วยระยะขอบ ฉันจะตบคลาสผู้ช่วยที่ชื่อ”

...
  .card__header-left
    = icon("arrow_backup", color: "gray25")
    %h2.--ml-10 Backups
...

ใน ทางเทคนิค แล้วดูเหมือนว่าม็อคอัพใช่ไหม! แน่นอน แต่สมมติว่าหนึ่งเดือนต่อมา นักพัฒนา รายอื่น ต้องการส่วนหัวของการ์ด แต่ไม่มีไอคอน พวกเขาพบตัวอย่างสุดท้าย คัดลอก/วาง และเพียงแค่ลบไอคอน

อีกครั้งมันดูถูกต้องใช่มั้ย? นอกบริบทสำหรับคนที่ไม่มีตาแหลมสำหรับการออกแบบแน่นอน! แต่ดูจากต้นฉบับแล้ว. ระยะขอบซ้ายบนชื่อเรื่องยังคงอยู่เพราะพวกเขาไม่ทราบว่าจำเป็นต้องลบตัวช่วยระยะขอบซ้ายออก!

นำตัวอย่างนี้ไปอีกขั้นหนึ่ง สมมติว่าต้นแบบอื่นเรียกส่วนหัวของการ์ดที่ไม่มีขอบด้านล่าง เราอาจพบสถานะที่เรามีในคู่มือสไตล์ที่เรียกว่า "ไร้ขอบ" และนำไปใช้นั้น สมบูรณ์แบบ!

นักพัฒนารายอื่นอาจพยายามใช้รหัสนั้นซ้ำ แต่ในกรณีนี้ พวกเขาต้องการเส้นขอบจริงๆ สมมติว่าพวกเขาละเลยการใช้งานที่เหมาะสมที่บันทึกไว้ในคู่มือสไตล์ และไม่ทราบว่าการลบคลาสไร้ขอบจะทำให้พวกเขามีขอบ แต่จะเพิ่มกฎแนวนอนแทน ท้ายที่สุดก็มีช่องว่างระหว่างหัวเรื่องกับเส้นขอบ ดังนั้นพวกเขาจึงใช้คลาสตัวช่วยกับ hr และ voila!

ด้วยการปรับเปลี่ยนส่วนหัวของการ์ดดั้งเดิมทั้งหมดเหล่านี้ ตอนนี้เรามีปัญหากับโค้ดในมือแล้ว

.card__header.--borderless
  .card__header-left
    %h2.--ml-10 Backups

  .card__header-right
    = link_to "#" do
      = icon("plus_small")

  %hr.--mt-0.--mb-0

โปรดทราบว่าตัวอย่างข้างต้นเป็นเพียงการแสดงให้เห็นจุดที่ส่วนประกอบที่ไม่มีข้อจำกัดสามารถกลายเป็นความยุ่งเหยิงเมื่อเวลาผ่านไปได้อย่างไร หากใครในทีมของเราพยายามจัดส่งส่วนหัวของการ์ดแบบต่างๆ ควร ตรวจพบโดยการตรวจสอบการออกแบบหรือการตรวจสอบโค้ด แต่บางครั้งสิ่งนี้ก็หลุดผ่านรอยแตกได้ ดังนั้นเราจึงจำเป็นต้องมีสิ่งกันกระสุน!


ส่วนประกอบที่มีข้อจำกัด

คุณอาจกำลังคิดว่าปัญหาข้างต้นได้รับการแก้ไขแล้วด้วยส่วนประกอบต่างๆ นั่นเป็นข้อสันนิษฐานที่ถูกต้อง! เฟรมเวิร์กส่วนหน้าเช่น React และ Vue ได้รับความนิยมอย่างมากสำหรับจุดประสงค์นี้ เป็นเครื่องมือที่ยอดเยี่ยมสำหรับการห่อหุ้ม UI อย่างไรก็ตาม มีข้อขัดข้องอย่างหนึ่งที่เราไม่ค่อยชอบนัก – พวกเขาต้องการให้ JavaScript แสดงผล UI ของคุณ

แอปพลิเคชัน Flywheel เป็นส่วนแบ็คเอนด์ที่หนักมาก โดยมี HTML ที่แสดงผลโดยเซิร์ฟเวอร์เป็นหลัก แต่โชคดีสำหรับเรา ส่วนประกอบสามารถมีได้หลายรูปแบบ ในตอนท้าย คอมโพเนนต์ UI เป็นการสรุปรูปแบบและกฎการออกแบบที่ส่งออกมาร์กอัปไปยังเบราว์เซอร์ ด้วยการตระหนักรู้นี้ เราสามารถใช้แนวทางเดียวกันนี้กับส่วนประกอบต่างๆ ได้ แต่ไม่มีโอเวอร์เฮดของเฟรมเวิร์ก JavaScript

เราจะพูดถึงวิธีที่เราสร้างองค์ประกอบที่มีข้อจำกัดด้านล่าง แต่นี่คือประโยชน์บางส่วนที่เราพบจากการใช้ส่วนประกอบเหล่านี้:

  • ไม่มีทางที่ผิดจริงๆ ในการรวมส่วนประกอบเข้าด้วยกัน
  • ส่วนประกอบจะออกแบบทุกอย่างให้กับคุณ (คุณเพียงแค่ผ่านในตัวเลือก!)
  • ไวยากรณ์สำหรับการสร้างส่วนประกอบมีความสอดคล้องกันมากและง่ายต่อการให้เหตุผล
  • หากจำเป็นต้องเปลี่ยนการออกแบบในส่วนประกอบ เราสามารถเปลี่ยนครั้งเดียวในส่วนประกอบและมั่นใจได้ว่ามีการอัปเดตทุกที่

การแสดงผลส่วนประกอบทางฝั่งเซิร์ฟเวอร์

เรากำลังพูดถึงอะไรโดยการจำกัดองค์ประกอบ? มาขุดกันเถอะ!

ดังที่ได้กล่าวไว้ก่อนหน้านี้ เราต้องการให้นักพัฒนาที่ทำงานในแอปพลิเคชัน Flywheel สามารถดูแบบจำลองการออกแบบของเพจ และสร้างหน้านั้นได้ทันทีโดยไม่มีสิ่งกีดขวาง นั่นหมายถึงวิธีการสร้าง UI จะต้อง A) จัดทำเป็นเอกสารอย่างดี และ B) เปิดเผยและไม่ต้องคาดเดามาก

บางส่วนเพื่อช่วยชีวิต (หรืออย่างที่เราคิด)

การแทงครั้งแรกที่เราได้ลองมาในอดีตคือการใช้ Rails บางส่วน บางส่วนเป็นเครื่องมือเดียวที่ Rails ให้คุณนำกลับมาใช้ใหม่ได้ในเทมเพลต โดยธรรมชาติแล้ว สิ่งเหล่านี้เป็นสิ่งแรกที่ทุกคนเอื้อมถึง แต่มีข้อเสียที่สำคัญที่ต้องพึ่งพาสิ่งเหล่านี้ เพราะถ้าคุณต้องการรวมตรรกะกับเทมเพลตที่นำกลับมาใช้ใหม่ได้ คุณมีสองทางเลือก: ทำซ้ำตรรกะในทุกตัวควบคุมที่ใช้บางส่วนหรือฝังตรรกะลงในบางส่วนเอง

บางส่วนจะป้องกันการคัดลอก/วางการทำซ้ำที่ผิดพลาด และทำงานได้ดีในสองสามครั้งแรกที่คุณต้องนำบางสิ่งกลับมาใช้ใหม่ แต่จากประสบการณ์ของเรา ส่วนที่ไม่สมบูรณ์ในไม่ช้านี้จะได้รับการสนับสนุนสำหรับฟังก์ชันการทำงานและตรรกะที่เพิ่มมากขึ้น แต่ตรรกะไม่ควรอยู่ในเทมเพลต!

ข้อมูลเบื้องต้นเกี่ยวกับเซลล์

โชคดีที่มีทางเลือกอื่นที่ดีกว่าบางส่วนที่ช่วยให้เราสามารถนำโค้ดกลับมาใช้ใหม่ได้ และ ป้องกันไม่ให้ลอจิกมองเห็นได้ เรียกว่า Cells อัญมณีทับทิมที่พัฒนาโดยเทรลเบลเซอร์ เซลล์มีมาก่อนความนิยมเพิ่มขึ้นในเฟรมเวิร์กส่วนหน้าเช่น React และ Vue และอนุญาตให้คุณเขียนโมเดลมุมมองที่ห่อหุ้มที่จัดการทั้งตรรกะ และ เทมเพลต พวกเขาให้มุมมองที่เป็นนามธรรมของโมเดลซึ่ง Rails ไม่ได้มีอยู่จริง ที่จริงแล้ว เราใช้ Cells ในแอป Flywheel มาระยะหนึ่งแล้ว ไม่ใช่แค่ในระดับสากลที่นำกลับมาใช้ใหม่ได้

ในระดับที่ง่ายที่สุด Cells อนุญาตให้เราสรุปส่วนมาร์กอัปเช่นนี้ (เราใช้ Haml สำหรับภาษาเทมเพลตของเรา):

%div
  %h1 Hello, world!

เป็นโมเดลมุมมองที่นำกลับมาใช้ใหม่ได้ (คล้ายกับบางส่วน ณ จุดนี้) และเปลี่ยนเป็นสิ่งนี้:

= cell("hello_world")

ในที่สุดสิ่งนี้จะช่วยให้เราจำกัดองค์ประกอบที่ไม่สามารถเพิ่มคลาสตัวช่วยหรือส่วนประกอบย่อยที่ไม่ถูกต้องโดยไม่ต้องแก้ไขเซลล์เอง

การสร้างเซลล์

เราใส่ UI Cells ทั้งหมดลงในไดเร็กทอรี app/cells/ui แต่ละเซลล์ต้องมีไฟล์ Ruby เพียงไฟล์เดียว ต่อท้ายด้วย _cell.rb ในทางเทคนิค คุณสามารถเขียนเทมเพลตใน Ruby ได้โดยตรงด้วยตัวช่วย content_tag แต่ Cells ส่วนใหญ่ของเรายังมีเทมเพลต Haml ที่สอดคล้องกันซึ่งอยู่ในโฟลเดอร์ที่ตั้งชื่อตามส่วนประกอบ

เซลล์พื้นฐานขั้นสุดยอดที่ไม่มีตรรกะจะมีลักษณะดังนี้:

// cells/ui/slat_cell.rb

module UI
  class SlatCell < ViewModel
    def show
    end
  end
end

วิธีการแสดงคือสิ่งที่แสดงผลเมื่อคุณสร้างเซลล์ และมันจะค้นหาไฟล์ show.haml ที่เกี่ยวข้องในโฟลเดอร์ที่มีชื่อเดียวกันกับเซลล์โดยอัตโนมัติ ในกรณีนี้ มันคือ app/cells/ui/slat (เรากำหนดขอบเขต UI Cells ทั้งหมดเป็นโมดูล UI)

ในเทมเพลต คุณสามารถเข้าถึงตัวเลือกที่ส่งผ่านไปยังเซลล์ได้ ตัวอย่างเช่น หากเซลล์สร้างอินสแตนซ์ในมุมมองเช่น = cell("ui/slat", title: "Title", subtitle: "Subtitle", label: "Label") เราสามารถเข้าถึงตัวเลือกเหล่านั้นได้ผ่านทางออบเจกต์ options

// cells/ui/slat/show.haml
.slat
  .slat__inner
    .slat__content
      %h4= options[:title]
      %p= options[:subtitle]
      = icon(options[:icon], color: "blue")

หลายครั้งที่เราจะย้ายองค์ประกอบธรรมดาและค่าขององค์ประกอบเหล่านั้นไปยังวิธีการในเซลล์เพื่อป้องกันไม่ให้องค์ประกอบว่างถูกแสดงผลหากไม่มีตัวเลือก

// cells/ui/slat_cell.rb
def title
  return unless options[:title]
  content_tag :h4, options[:title]
end

def subtitle
  return unless options[:subtitle]
  content_tag :p, options[:subtitle]
end
// cells/ui/slat/show.haml
.slat
  .slat__inner
    .slat__content
      = title
      = subtitle

การห่อเซลล์ด้วยยูทิลิตี้ UI

หลังจากพิสูจน์แนวคิดที่ว่าสิ่งนี้สามารถใช้ได้ในวงกว้าง ฉันต้องการจัดการกับมาร์กอัปที่ไม่เกี่ยวข้องซึ่งจำเป็นต่อการเรียกใช้เซลล์ มันไหลไม่ถูกต้องนักและจำยาก ดังนั้นเราจึงสร้างตัวช่วยเล็กน้อยสำหรับมัน! ตอนนี้เราสามารถเรียก = ui “name_of_component” และส่งตัวเลือกในบรรทัด

= ui "slat", title: "Title", subtitle: "Subtitle", label: "Label"

ส่งตัวเลือกเป็นบล็อกแทนอินไลน์

การใช้ยูทิลิตี UI เพิ่มขึ้นอีกเล็กน้อย เห็นได้ชัดว่าเซลล์ที่มีตัวเลือกมากมายในบรรทัดเดียวนั้นยากต่อการติดตามและน่าเกลียดมาก ต่อไปนี้คือตัวอย่างของเซลล์ที่มีตัวเลือกมากมายที่กำหนดไว้แบบอินไลน์:

= ui “slat", title: “Title”, subtitle: “Subtitle”, label: “Label”, link: “#”, tertiary_title: “Tertiary”, disabled: true, checklist: [“Item 1”, “Item 2”, “Item 3”]

เป็นเรื่องที่ยุ่งยากมาก ซึ่งทำให้เราต้องสร้างคลาสที่ชื่อว่า OptionProxy ซึ่งสกัดกั้นเมธอด Cells setter และแปลงเป็นค่าแฮช ซึ่งจะถูกรวมเข้ากับตัวเลือกต่างๆ ถ้ามันฟังดูซับซ้อน ไม่ต้องกังวล มันซับซ้อนสำหรับฉันเช่นกัน นี่คือส่วนสำคัญของคลาส OptionProxy ที่ Adam หนึ่งในวิศวกรซอฟต์แวร์อาวุโสของเราเขียนไว้

นี่คือตัวอย่างการใช้คลาส OptionProxy ภายในเซลล์ของเรา:

module UI
  class SlatCell < ViewModel
    def show
      OptionProxy.new(self).yield!(options, &block)
      super()
    end
  end
end

เมื่อพร้อมแล้ว เราสามารถเปลี่ยนตัวเลือกอินไลน์ที่ยุ่งยากให้กลายเป็นบล็อกที่น่าพึงพอใจยิ่งขึ้นได้!

= ui "slat" do |slat|
  - slat.title = "Title"
  - slat.subtitle = "Subtitle"
  - slat.label = "Label"
  - slat.link = "#"
  - slat.tertiary_title = "Tertiary"
  - slat.disabled = true
  - slat.checklist = ["Item 1", "Item 2", "Item 3"]

แนะนำตรรกะ

จนถึงตอนนี้ ตัวอย่างยังไม่ได้รวมตรรกะใดๆ เกี่ยวกับสิ่งที่มุมมองแสดง นั่นเป็นหนึ่งในสิ่งที่ดีที่สุดที่ Cells นำเสนอ มาคุยกันเถอะ!

ในการผสานกับองค์ประกอบ slat ของเรา บางครั้งเราจำเป็นต้องแสดงสิ่งทั้งหมดเป็นลิงก์ และบางครั้งแสดงผลเป็น div ขึ้นอยู่กับว่ามีตัวเลือกลิงก์หรือไม่ ฉันเชื่อว่านี่เป็นองค์ประกอบเดียวที่เรามีซึ่งสามารถแสดงเป็น div หรือลิงก์ได้ แต่เป็นตัวอย่างที่ดีของพลังของเซลล์

วิธีการด้านล่างเรียก link_to หรือตัวช่วย content_tag ขึ้นอยู่กับการมีอยู่ของตัวเลือก [:link]

หมายเหตุ: สิ่งนี้ได้รับแรงบันดาลใจและสร้างสรรค์โดย Adam Lassek ซึ่งมีอิทธิพลอย่างมากในการช่วยเราสร้างวิธีการพัฒนา UI ทั้งหมดด้วย Cells

def container(&block)
  tag =
    if options[:link]
      [:link_to, options[:link]]
    else
      [:content_tag, :div]
    end

  send(*tag, class: “slat__inner”, &block)
end

ที่ช่วยให้เราสามารถแทนที่องค์ประกอบ .slat__inner ในเทมเพลตด้วยคอนเทนเนอร์บล็อก:

.slat
  = container do
  ...

อีกตัวอย่างหนึ่งของตรรกะในเซลล์ที่เราใช้บ่อยคือคลาสเอาต์พุตแบบมีเงื่อนไข สมมติว่าเราเพิ่มตัวเลือกที่ปิดใช้งานลงในเซลล์ ไม่มีอะไรอื่นในการเรียกใช้เซลล์เปลี่ยนแปลง นอกจากที่คุณสามารถส่งผ่านตัวเลือกที่ปิดใช้งาน: จริง และดูว่าสิ่งทั้งหมดเปลี่ยนเป็นสถานะปิดใช้งาน (เป็นสีเทาพร้อมลิงก์ที่ไม่สามารถคลิกได้)

= ui "slat" do |slat|
  ...
  - slat.disabled = true

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

.slat{ class: possible_classes("--disabled": options[:disabled]) }
  .slat__inner
    .slat__content
      %h4{ class: possible_classes("--alt": options[:disabled]) }= options[:title]
      %p{ class: possible_classes("--alt": options[:disabled]) }=
      options[:subtitle]
      = icon(options[:icon], color: "gray")

ตามเนื้อผ้า เราจะต้องจำ (หรืออ้างอิงคู่มือสไตล์) ว่าแต่ละองค์ประกอบจำเป็นต้องมีคลาสเพิ่มเติมเพื่อให้สิ่งทั้งหมดทำงานอย่างถูกต้องในสถานะปิดการใช้งาน เซลล์ช่วยให้เราสามารถประกาศทางเลือกหนึ่งแล้วทำภารกิจหนักๆ ให้เราได้

หมายเหตุ: possible_classes เป็นวิธีการที่เราสร้างขึ้นเพื่ออนุญาตให้ใช้คลาสแบบมีเงื่อนไขใน Haml ในทางที่ดี


ที่เราไม่สามารถใช้ส่วนประกอบฝั่งเซิร์ฟเวอร์ได้

แม้ว่าวิธีเซลล์จะมีประโยชน์อย่างมากสำหรับแอปพลิเคชันเฉพาะของเราและวิธีทำงานของเรา แต่ฉันไม่อยากจะบอกว่าวิธีนี้แก้ปัญหาได้ 100% เรายังคงเขียน JavaScript (จำนวนมาก) และสร้างประสบการณ์บางอย่างใน Vue ตลอดทั้งแอปของเรา 75% ของเวลาทั้งหมด เทมเพลต Vue ของเรายังคงอยู่ใน Haml และเราผูกอินสแตนซ์ Vue ของเรากับองค์ประกอบที่มีอยู่ ซึ่งช่วยให้เรายังคงใช้ประโยชน์จากแนวทางเซลล์

อย่างไรก็ตาม ในสถานที่ที่เหมาะสมกว่าที่จะจำกัดองค์ประกอบให้เป็นอินสแตนซ์ Vue ไฟล์เดียว เราไม่สามารถใช้ Cells ได้ ตัวอย่างเช่น รายการที่เราเลือกคือ Vue ทั้งหมด แต่ฉันคิดว่าไม่เป็นไร! เราไม่จำเป็นต้องมีส่วนประกอบเวอร์ชันที่ซ้ำกันทั้งในส่วนประกอบ Cells และ Vue ดังนั้นจึงเป็นเรื่องปกติที่ส่วนประกอบบางส่วนจะสร้างด้วย Vue 100% และบางส่วนใช้ Cells หากส่วนประกอบถูกสร้างขึ้นด้วย Vue หมายความว่า JavaScript จำเป็นต้องสร้างมันใน DOM และเราใช้ประโยชน์จากกรอบงาน Vue เพื่อทำเช่นนั้น สำหรับส่วนประกอบอื่นๆ ส่วนใหญ่ของเรา พวกมันไม่ต้องการ JavaScript และหากจำเป็น พวกเขาต้องการ DOM ที่ถูกสร้างขึ้นแล้ว และเราเพียงแค่เชื่อมต่อและเพิ่มตัวฟังเหตุการณ์

ในขณะที่เราดำเนินการตามแนวทางของเซลล์ต่อไป เราจะทำการทดลองกับส่วนประกอบของเซลล์และส่วนประกอบ Vue อย่างแน่นอน เพื่อให้เรามีวิธีเดียวในการสร้างและใช้ส่วนประกอบ ไม่รู้ว่าหน้าตาเป็นยังงัย ไปถึงแล้วจะข้ามสะพานนั้นไป!


บทสรุปของเรา

จนถึงตอนนี้ เราได้แปลงองค์ประกอบภาพที่ใช้มากที่สุดประมาณสามสิบรายการเป็นเซลล์ มันให้ประสิทธิภาพการทำงานอย่างมหาศาลแก่เรา และให้นักพัฒนารู้สึกว่าได้รับประสบการณ์ที่พวกเขากำลังสร้างนั้นถูกต้องและไม่ถูกแฮ็กร่วมกัน

ทีมออกแบบของเรามั่นใจมากขึ้นกว่าเดิมว่าส่วนประกอบและประสบการณ์ในแอปของเราเป็นแบบ 1:1 กับสิ่งที่พวกเขาออกแบบใน Adobe XD การเปลี่ยนแปลงหรือเพิ่มเติมส่วนประกอบได้รับการจัดการผ่านการโต้ตอบกับนักออกแบบและนักพัฒนาส่วนหน้าเท่านั้น ซึ่งช่วยให้ทีมที่เหลือมีสมาธิและไม่ต้องกังวลกับการรู้วิธีปรับแต่งส่วนประกอบให้เข้ากับการจำลองการออกแบบ

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


มาทำงานที่ Flywheel!

ที่ Flywheel ทุกแผนกมีผลกระทบอย่างมีนัยสำคัญต่อลูกค้าและผลกำไรของเรา ไม่ว่าจะเป็นการสนับสนุนลูกค้า การพัฒนาซอฟต์แวร์ การตลาด หรืออะไรก็ตาม เราทุกคนกำลังทำงานร่วมกันเพื่อมุ่งสู่ภารกิจของเราในการสร้างบริษัทโฮสติ้งที่ผู้คนสามารถตกหลุมรักได้อย่างแท้จริง

พร้อมที่จะเข้าร่วมทีมของเราแล้วหรือยัง? เรากำลังจ้าง! สมัครได้ที่นี่.