How to Create Nested LiveView Components: Difference between revisions
From ElixirBlocks
No edit summary |
No edit summary |
||
Line 29: | Line 29: | ||
end | end | ||
end | end | ||
</source> | |||
An Example of a Button | |||
<source> | |||
# 1. Create component with phx-click attributes for event handlers and a render slot fo text: <%= render_slot(@inner_block) %> | |||
defmodule Example do | |||
use Phoenix.Component | |||
def simple_button(assigns) do | |||
~H""" | |||
<button | |||
style="background-color: #000000; color: #ffffff; padding: 8px 16px; border-radius: 4px; font-weight: bold;" | |||
phx-click={@on_click} | |||
> | |||
<%= render_slot(@inner_block) %> | |||
</button> | |||
""" | |||
end | |||
end | |||
#___________PARENT | |||
defmodule AppWeb.PageLive do | |||
use AppWeb, :live_view | |||
import Example | |||
def mount(_params, _session, socket) do | |||
# Initialize state with a counter | |||
socket = assign(socket, count: 0) | |||
{:ok, socket} | |||
end | |||
def render(assigns) do | |||
~H""" | |||
<div class="container mx-auto p-4"> | |||
<h1 class="text-xl font-bold mb-4">Counter with Button Component</h1> | |||
<div class="mb-4"> | |||
<p>Current count: <span class="font-bold"><%= @count %></span></p> | |||
</div> | |||
<!-- # 2 add component to parent. Event handlers will come from parent--> | |||
<Example.simple_button on_click="increment"> | |||
<span>Click to increment</span> | |||
</Example.simple_button> | |||
</div> | |||
""" | |||
end | |||
# Event handler in the parent LiveView | |||
def handle_event("increment", _params, socket) do | |||
{:noreply, assign(socket, count: socket.assigns.count + 1)} | |||
end | |||
end | |||
</source> | </source> |
Revision as of 18:32, 13 March 2025
This example demonstrates a nested LiveView component.
defmodule AppxWeb.SandboxLive do use AppxWeb, :live_view import MyComponent def mount(_params, _session, socket) do {:ok, socket} end def render(assigns) do ~H""" Hello World! YAY <MyComponent.greet name="Jane" /> """ end end
defmodule MyComponent do use Phoenix.Component def greet(assigns) do ~H""" <p>Hello, <%= @name %>!</p> """ end end
An Example of a Button
# 1. Create component with phx-click attributes for event handlers and a render slot fo text: <%= render_slot(@inner_block) %> defmodule Example do use Phoenix.Component def simple_button(assigns) do ~H""" <button style="background-color: #000000; color: #ffffff; padding: 8px 16px; border-radius: 4px; font-weight: bold;" phx-click={@on_click} > <%= render_slot(@inner_block) %> </button> """ end end #___________PARENT defmodule AppWeb.PageLive do use AppWeb, :live_view import Example def mount(_params, _session, socket) do # Initialize state with a counter socket = assign(socket, count: 0) {:ok, socket} end def render(assigns) do ~H""" <div class="container mx-auto p-4"> <h1 class="text-xl font-bold mb-4">Counter with Button Component</h1> <div class="mb-4"> <p>Current count: <span class="font-bold"><%= @count %></span></p> </div> <!-- # 2 add component to parent. Event handlers will come from parent--> <Example.simple_button on_click="increment"> <span>Click to increment</span> </Example.simple_button> </div> """ end # Event handler in the parent LiveView def handle_event("increment", _params, socket) do {:noreply, assign(socket, count: socket.assigns.count + 1)} end end