It is a gem made by github. https://github.com/github/view_component
It's like a power-up version of render partial, which seems to be useful when you want to reuse the view code or write tests.
Since ruby and template can be prepared as a set like this, it seems that it is easier to write logic and data transfer compared to partial.
app/components/test_component.rb
class TestComponent < ViewComponent::Base
def initialize(title:)
@title = title
end
end
erb:app/components/test_component.html.erb
<span title="<%= @title %>"><%= content %></span>
It looks like this when calling.
<%= render(TestComponent.new(title: "my title")) do %>
Hello, World!
<% end %>
Apart from the defined @ title
, the content passed in block is automatically assigned to the accessor called content
.
You can add a gem and install it with bundle install
.
gem "view_component", require: "view_component/engine"
It seems to work with rails 5.0 and above. However, if it is less than rails 6.1, it seems that the render method will be patched with a monkey.
You can also use render_component
if you don't want to apply the monkey patch.
config.view_component.render_monkey_patch_enabled = false # defaults to true
<%= render_component Component.new(message: "bar") %>
Let's create a view_component with the rails command.
bin/rails generate component Example title
A set of files is created like this.
Running via Spring preloader in process 407
create app/components/example_component.rb
invoke test_unit
create test/components/example_component_test.rb
invoke erb
create app/components/example_component.html.erb
You can check view_componet in preview like ActionMailer.
test/components/previews/test_component_preview.rb
class TestComponentPreview < ViewComponent::Preview
def with_default_title
render(TestComponent.new(title: "Test component default"))
end
def with_long_title
render(TestComponent.new(title: "This is a really long title to see how the component renders this"))
end
def with_content_block
render(TestComponent.new(title: "This component accepts a block of content")) do
tag.div do
content_tag(:span, "Hello")
end
end
end
end
Now you can check the preview by accessing the url below. http://localhost:3000/rails/view_components/test_component/with_default_title http://localhost:3000/rails/view_components/test_component/with_long_title http://localhost:3000/rails/view_components/test_component/with_content_block
You can test the content by calling view_component with render_inline
.
require "test_helper"
class HelloComponentTest < ViewComponent::TestCase
def test_component_renders_something_useful
assert_equal(
%(<div>hello bob</div>),
render_inline(HelloComponent.new(name: "bob")).css("div").to_html
)
end
end
It seems that there are various functions other than those introduced this time, so if you are interested, please see the official document. https://viewcomponent.org/
Recommended Posts