Rails 5.1+의 간단한보기 구성 요소, Elemental_StyleGuide와 잘 맞도록 설계되었습니다. 둘이 함께 브래드 프로스트의 작품과 Lonely Planet 's Style Guide Rizzo의 생각에서 영감을 얻었습니다.
이 라인을 응용 프로그램의 보석에 추가하십시오.
gem "elemental_components"그런 다음 실행 :
$ bundle여기에 제공된 예제는 BEM 명명 규칙을 사용합니다.
구성 요소는 app/components 에 살고 있습니다. 실행하여 구성 요소를 생성합니다.
$ bin/rails g elemental_components:component alert다음 파일이 생성됩니다.
app/
components/
alert/
_alert.html.erb
alert.css
alert.js
alert_component.rb
생성기는 또한 --skip-css 및 --skip-js 옵션을 사용합니다.
마크 업과 CSS를 추가합시다.
<% # app/components/alert/_alert.html.erb %>
< div class =" alert alert--primary " role =" alert " >
Message
</ div > /* app/components/alert/alert.css */
. alert {
padding : 1 rem ;
}
. alert--primary {
background : blue;
}
. alert--success {
background : green;
}
. alert--danger {
background : red;
} 이 구성 요소는 이제 component 도우미를 사용하여 렌더링 할 수 있습니다.
<%= component "alert" %> CSS와 같은 자산을 요구하려면 매니페스트 (예 : application.css )에서 수동으로 필요합니다.
/*
*= require alert/alert
*/ 또는 components 필요하므로 모든 구성 요소의 자산이 필요합니다.
/*
*= require elemental_components
*/데이터를 구성 요소로 전달하는 두 가지 방법이 있습니다 : 속성 및 컨텐츠 블록. 속성은 ID, 수정 자 및 데이터 구조 (모델 등)와 같은 데이터에 유용합니다. 컨텐츠 블록은 HTML 컨텐츠를 구성 요소에 주입해야 할 때 유용합니다.
방금 만든 구성 요소에 대한 몇 가지 속성을 정의해 봅시다.
# app/components/alert_component.rb %>
class AlertComponent < ElementalComponents :: Component
attribute :context
attribute :message
end <% # app/components/alert/_alert.html.erb %>
< div class =" alert alert-- <%= alert.context %> " role =" alert " >
<%= alert.message %>
</ div > <%= component "alert", message: "Something went right!", context: "success" %>
<%= component "alert", message: "Something went wrong!", context: "danger" %> 구성 요소에 일부 텍스트 또는 HTML 컨텐츠를 주입하려면 구성 요소를 인쇄 할 수 있습니다.
<% # app/components/alert/_alert.html.erb %>
< div class =" alert alert-- <%= alert.context %> " role =" alert " >
<%= alert.content %>
</ div > <%= component "alert", context: "success" do %>
< em > Something </ em > went right!
<% end %>속성에 대한 또 다른 좋은 사용 사례는 모델에 의해 뒷받침되는 구성 요소가있는 경우입니다.
# app/components/comment_component.rb %>
class CommentComponent < ElementalComponents :: Component
attribute :comment
delegate :id ,
:author ,
:body , to : :comment
end <% # app/components/comment/_comment.html.erb %>
< div id =" comment- <%= comment.id %> " class =" comment " >
< div class =" comment__author " >
<%= link_to comment.author.name, author_path(comment.author) %>
</ div >
< div class =" comment__body " >
<%= comment.body %>
</ div >
</ div > <% comments.each do |comment| %>
<%= component "comment", comment: comment %>
<% end %> 속성은 기본값을 가질 수 있습니다.
# app/components/alert_component.rb %>
class AlertComponent < ElementalComponents :: Component
attribute :message
attribute :context , default : "primary"
end추가 로직으로 속성을 재정의하는 것은 쉽습니다.
# app/components/alert_component.rb %>
class AlertComponent < ElementalComponents :: Component
attribute :message
attribute :context , default : "primary"
def message
@message . upcase if context == "danger"
end
end 구성 요소가 제대로 초기화되도록하려면 ActiveModel::Validations 사용할 수 있습니다.
# app/components/alert_component.rb %>
class AlertComponent < ElementalComponents :: Component
attribute :label
validates :label , presence : true
end 유효성 검사는 구성 요소 초기화 중에 실행되며 유효성 검사가 실패하면 ActiveModel::ValidationError 올리십시오.
속성 및 블록은 모델과 같은 데이터 구조에 의해 뒷받침되는 간단한 구성 요소 또는 구성 요소에 적합합니다. 다른 구성 요소는 본질적으로 더 일반적이며 다양한 상황에서 사용할 수 있습니다. 종종 그들은 여러 부분이나 요소로 구성되며 때로는 반복되며 때로는 자체 수정자가 필요합니다.
카드 구성 요소를 가져 가십시오. React에서 일반적인 접근 방식은 하위 구성 요소를 만드는 것입니다.
< Card flush = { true } >
< CardHeader centered = { true } >
Header
</ CardHeader >
< CardSection size = "large" >
Section 1
</ CardSection >
< CardSection size = "small" >
Section 2
</ CardSection >
< CardFooter >
Footer
</ CardFooter >
</ Card >이 접근법에는 다음과 같은 두 가지 문제가 있습니다.
CardHeader Card 외부에 배치 될 수 있음을 의미합니다.CardHeader 아래 또는 CardFooter 안에 배치 할 수 있습니다.이 보석을 사용하면 동일한 구성 요소를 다음과 같이 쓸 수 있습니다.
# app/components/card_component.rb %>
class CardComponent < ElementalComponents :: Component
attribute :flush , default : false
element :header do
attribute :centered , default : false
end
element :section , multiple : true do
attribute :size
end
element :footer
end <% # app/components/card/_card.html.erb %>
< div class =" card <%= "card--flush" if card.flush %> " >
<% if card.header.content? %>
< div class =" card__header <%= "card__header--centered" if card.header.centered %> " >
<%= card.header.content %>
</ div >
<% end %>
<% card.sections.each do |section| %>
< div class =" card__section <%= "card__section--#{section.size}" %> " >
<%= section.content %>
</ div >
<% end %>
<% if card.footer.content? %>
< div class =" card__footer " >
<%= card.footer.content %>
</ div >
<% end %>
</ div > 요소는 분리 된 하위 구성 요소로 생각할 수 있으며 구성 요소에 정의됩니다. multiple: true 는 반복 요소가되고 블록을 전달하면 구성 요소에 속성을 선언하는 것과 같은 방식으로 요소에 속성을 선언 할 수 있습니다.
데이터로 채우기 위해서는 구성 요소에 블록을 전달하여 구성 요소를 산출하여 구성 요소와 같은 방식으로 요소에 속성 및 컨텐츠 블록을 설정할 수 있습니다.
<%= component "card", flush: true do |c| %>
<% c.header centered: true do %>
Header
<% end %>
<% c.section size: "large" do %>
Section 1
<% end %>
<% c.section size: "large" do %>
Section 2
<% end %>
<% c.footer do %>
Footer
<% end %>
<% end %> 위의 예제의 section 과 같은 반복 요소에 대한 여러 호출은 각 섹션을 배열에 추가합니다.
또 다른 좋은 사용 사례는 내비게이션 구성 요소입니다.
# app/components/navigation_component.rb %>
class NavigationComponent < ElementalComponents :: Component
element :items , multiple : true do
attribute :label
attribute :url
attribute :active , default : false
end
end <%= component "navigation" do |c| %>
<% c.item label: "Home", url: root_path, active: true %>
<% c.item label: "Explore" url: explore_path %>
<% end %> 여기서 대안은 구성 요소를 렌더링 할 때 HTML을 주입 할 필요가없는 경우 데이터 구조를 구성 요소로 전달하는 것입니다.
<%= component "navigation", items: items %> 요소도 검증을 가질 수 있습니다.
class NavigationComponent < ElementalComponents :: Component
element :items , multiple : true do
attribute :label
attribute :url
attribute :active , default : false
validates :label , presence : true
validates :url , presence : true
end
end요소는 중첩 될 수도 있지만 최소한으로 계속 중첩하는 것이 좋습니다.
# app/components/card_component.rb %>
class CardComponent < ElementalComponents :: Component
...
element :section , multiple : true do
attribute :size
element :header
element :footer
end
end속성 및 요소를 선언하는 것 외에도 도우미 방법을 선언 할 수도 있습니다. 이것은 템플릿에서 논리를 유지하는 것을 선호하는 경우 유용합니다. 카드 구성 요소 템플릿에서 수정 자 논리를 추출하겠습니다.
# app/components/card_component.rb %>
class CardComponent < ElementalComponents :: Component
...
def css_classes
css_classes = [ "card" ]
css_classes << "card--flush" if flush
css_classes . join ( " " )
end
end <% # app/components/card/_card.html.erb %>
<%= content_tag :div, class: card.css_classes do %>
...
<% end %>요소에 대한 도우미를 선언 할 수도 있습니다.
# app/components/card_component.rb %>
class CardComponent < ElementalComponents :: Component
...
element :section , multiple : true do
attribute :size
def css_classes
css_classes = [ "card__section" ]
css_classes << "card__section-- #{ size } " if size
css_classes . join ( " " )
end
end
end <% # app/components/card/_card.html.erb %>
<%= content_tag :div, class: card.css_classes do %>
...
<%= content_tag :div, class: section.css_classes do %>
<%= section %>
<% end %>
...
<% end %> 헬퍼 메소드는 link_to 또는 content_tag 와 같은 Rails 도우미를 호출하기 위해 @view 인스턴스 변수를 사용할 수도 있습니다.
버튼과 같은 일부 작은 구성 요소의 경우 렌더링 속도를 높이기 위해 부분적으로 건너 뛰는 것이 합리적 일 수 있습니다. 구성 요소에서 render 재정의하여 수행 할 수 있습니다.
# app/components/button_component.rb %>
class ButtonComponent < ElementalComponents :: Component
attribute :label
attribute :url
attribute :context
def render
@view . link_to label , url , class : css_classes
end
def css_classes
css_classes = "button"
css_classes << "button-- #{ context } " if context
css_classes . join ( " " )
end
end <%= component "button", label: "Sign up", url: sign_up_path, context: "primary" %>
<%= component "button", label: "Sign in", url: sign_in_path %> 구성 요소는 네임 스페이스 아래 중첩 될 수 있습니다. 이것은 원자 디자인, Bemit 또는 기타 구성 요소 분류 체계와 같은 것을 연습하려는 경우 유용합니다. 네임 스펙트 한 구성 요소를 만들려면 폴더에 넣고 클래스를 모듈로 감싸십시오.
module Objects
class MediaObject < ElementalComponents :: Component ; end
end그런 다음 그렇게 템플릿에서 호출하십시오.
<%= component "objects/media_object" %> 이 도서관은 Elemental_StyleGuide와 함께 원자 디자인 및 생활 스타일 가이드에 관한 Brad Frost의 저술과 Lonely Planet 스타일 가이드 인 Rizzo에서 영감을 받았습니다. 다른 영감은 다음과 같습니다.
실제 세계 스타일 가이드 목록은 http://styleguides.io를 확인하십시오.