This guide will walk you through creating a simple counter application that demonstrates the basics of Phoenix LiveView.
Step 1: Setting up a new Phoenix project
First, make sure you have Elixir and Phoenix installed. Then, create a new Phoenix project:
# Install Phoenix (if you haven't already)
mix archive.install hex phx_new
# Create a new Phoenix project with LiveView
mix phx.new counter_app --live
# Move into the project directory
cd counter_app
# Set up the database (we won't use it much, but it's required)
mix ecto.setup
Step 2: Create a simple counter LiveView
Create a new file at lib/counter_app_web/live/counter_live.ex
:
defmodule CounterAppWeb.CounterLive do
# Use the LiveView functionality from the web module
use CounterAppWeb, :live_view
# mount/3 is called when the LiveView is first rendered
# It sets up the initial state of the LiveView
def mount(_params, _session, socket) do
# Initialize the socket with a count of 0
# assign/2 is used to set values in the socket's state
{:ok, assign(socket, count: 0)}
end
# handle_event/3 processes events sent from the client
# This function handles the "increment" event
def handle_event("increment", _params, socket) do
# Update the count by adding 1
# update/3 modifies an existing assign value
{:noreply, update(socket, :count, &(&1 + 1))}
end
# This function handles the "decrement" event
def handle_event("decrement", _params, socket) do
# Update the count by subtracting 1
{:noreply, update(socket, :count, &(&1 - 1))}
end
# This function handles the "reset" event
def handle_event("reset", _params, socket) do
# Reset the count to 0
{:noreply, assign(socket, count: 0)}
end
# render/1 defines what HTML to display
# It receives the socket's assigns as its argument
def render(assigns) do
~H"""
<div class="counter-container">
<h1>Simple Counter App</h1>
<!-- Display the current count from assigns -->
<h2>Count: <%= @count %></h2>
<div class="buttons">
<!-- phx-click specifies which event to trigger when the button is clicked -->
<button phx-click="decrement" class="button">-</button>
<button phx-click="reset" class="button">Reset</button>
<button phx-click="increment" class="button">+</button>
</div>
</div>
"""
end
end
Step 3: Add the route for our LiveView
Edit lib/counter_app_web/router.ex
to add a route for our counter:
defmodule CounterAppWeb.Router do
use CounterAppWeb, :router
# Pipeline definitions (already included when you create a new project)
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, html: {CounterAppWeb.Layouts, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
# Browser routes
scope "/", CounterAppWeb do
pipe_through :browser
# Add this line to direct the root path to our CounterLive module
live "/", CounterLive
end
# Other route groups would go here
end
Step 4: Add some basic CSS
Edit assets/css/app.css
to add some styling for our counter:
/* Add this to the bottom of the file */
/* Container for the counter application */
.counter-container {
max-width: 500px;
margin: 0 auto;
padding: 20px;
text-align: center;
font-family: system-ui, sans-serif;
}
/* Style for the buttons */
.buttons {
display: flex;
justify-content: center;
gap: 10px;
margin-top: 20px;
}
.button {
padding: 10px 20px;
font-size: 18px;
border: none;
border-radius: 4px;
background-color: #4a6da7;
color: white;
cursor: pointer;
transition: background-color 0.3s;
}
.button:hover {
background-color: #2c4a7c;
}
Step 5: Run the application
Start the Phoenix server:
mix phx.server
Visit http://localhost:4000
in your browser, and you should see your counter application running!
Understanding the LiveView Flow
-
When a user visits the page:
- The
mount/3
function is called, initializing the state withcount: 0
- The
render/1
function generates the initial HTML
- The
-
When a user clicks a button:
- The
phx-click
attribute tells LiveView which event to trigger - LiveView sends this event to the server through the WebSocket connection
- The corresponding
handle_event/3
function is called on the server - The state is updated accordingly
- The
render/1
function is called again to update the HTML - LiveView sends only the differences (patches) to the browser to update the DOM
- The
This is all handled automatically by LiveView, giving you real-time updates without writing any JavaScript!
Next Steps
To expand this application, you could:
- Add more complex state management
- Create LiveComponents for reusable UI elements
- Implement form validation
- Add persistence with Ecto and a database
Congratulations! You've created your first Phoenix LiveView application.
Top comments (0)