在開始解釋 LiveView 流程之前,我們要直接實作一個有簡單互動的 LiveView 頁面。
與 Controller-View 一樣,所有的連線都是從 Router 開始。我們在 router.ex 裡使用 live
加入一個 LiveView 的路由:
live(path, live_view, action \\ nil, opts \\ [])
scope "/", GratitudeWeb do
pipe_through :browser
get "/", PageController, :home
resources "/notes", NoteController, except: [:show]
live "/demo", DemoLive # <== 加入這一行
end
可能已經猜到了,接下來我們要建立一個 DemoLive 的 LiveView module。
LiveView 的 module 與 Controller 不同,是放在 live
資料夾裡面。我們建立一個 lib/gratitude_web/live/demo_live.ex
檔案,並加入以下程式碼:
defmodule GratitudeWeb.DemoLive do
use GratitudeWeb, :live_view
def mount(_params, _session, socket) do
{:ok, assign(socket, message: "第一個 LiveView 頁面!")}
end
def render(assigns) do
~H"""
<h1><%= @message %></h1>
"""
end
end
完成了,現在打開瀏覽器到 localhost:4000/demo
就可以看到我們的第一個 LiveView 頁面了!
當 Phoenix 收到 /demo
時
/demo
對應的 DemoLive
moduleDemoLive
裡面的 mount
assign
在 socket 裡面的 assigns
加入 message
DemoLive
裡面的 render
並回傳 HTML當然目前這樣的靜態畫面 Controller-View 也可以做到,接下來幫 DemoLive 加入一個簡單的互動功能。
defmodule GratitudeWeb.DemoLive do
use GratitudeWeb, :live_view
def mount(_params, _session, socket) do
{:ok, assign(socket, message: "第一個 LiveView 頁面!", card: "🂠")}
end
def handle_event("random_emoji", _params, socket) do
new_card = Enum.random(["🂡", "🂢", "🂣", "🂤", "🂥", "🂦", "🂧", "🂨", "🂩", "🂪", "🂫", "🂭", "🂮"])
{:noreply, assign(socket, message: "抽到了", card: new_card)}
end
def render(assigns) do
~H"""
<.button phx-click="random_emoji">抽一張牌</.button>
<h1><%= @message %></h1>
<p class="text-9xl"><%= @card %></p>
"""
end
end
在點擊「抽一張牌」按鈕時會觸發 phx-click="random_emoji"
,這會呼叫伺服器端的 handle_event("random_emoji", _params, socket)
,在接收到後我們可以去改變伺服器的 assigns 狀態,這次我們把原本在 mount
階段定義在 assigns 裡的 card
更換成另一張隨機的卡。
我們不需要處理實際更新畫面的部分,每當 assigns 有變動時,LiveView 會自動呼叫 render
並更新畫面。