Phoenix简介 #
一、Phoenix概述 #
1.1 什么是Phoenix #
Phoenix是Elixir最流行的Web框架,提供高性能、可扩展的Web应用开发体验。
1.2 Phoenix特点 #
- 高性能
- 实时功能(WebSocket)
- 内置热重载
- 强大的路由系统
- 模板引擎(HEEx)
二、创建项目 #
2.1 安装Phoenix #
bash
mix archive.install hex phx_new
2.2 创建新项目 #
bash
mix phx.new my_app
cd my_app
2.3 项目结构 #
text
my_app/
├── lib/
│ ├── my_app/
│ │ ├── application.ex
│ │ └── repo.ex
│ └── my_app_web/
│ ├── endpoint.ex
│ ├── router.ex
│ ├── controllers/
│ ├── views/
│ └── templates/
├── config/
├── priv/
└── test/
三、路由 #
3.1 路由定义 #
elixir
defmodule MyAppWeb.Router do
use MyAppWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {MyAppWeb.Layouts, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", MyAppWeb do
pipe_through :browser
get "/", PageController, :home
resources "/users", UserController
end
scope "/api", MyAppWeb do
pipe_through :api
resources "/posts", PostController, only: [:index, :show]
end
end
3.2 RESTful路由 #
elixir
resources "/users", UserController
生成路由:
| 方法 | 路径 | 控制器动作 |
|---|---|---|
| GET | /users | index |
| GET | /users/new | new |
| POST | /users | create |
| GET | /users/:id | show |
| GET | /users/:id/edit | edit |
| PUT | /users/:id | update |
| DELETE | /users/:id | delete |
3.3 嵌套路由 #
elixir
resources "/users", UserController do
resources "/posts", PostController
end
四、控制器 #
4.1 控制器定义 #
elixir
defmodule MyAppWeb.UserController do
use MyAppWeb, :controller
alias MyApp.Accounts
alias MyApp.Accounts.User
def index(conn, _params) do
users = Accounts.list_users()
render(conn, :index, users: users)
end
def show(conn, %{"id" => id}) do
user = Accounts.get_user!(id)
render(conn, :show, user: user)
end
def new(conn, _params) do
changeset = Accounts.change_user(%User{})
render(conn, :new, changeset: changeset)
end
def create(conn, %{"user" => user_params}) do
case Accounts.create_user(user_params) do
{:ok, user} ->
conn
|> put_flash(:info, "User created successfully.")
|> redirect(to: ~p"/users/#{user}")
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, :new, changeset: changeset)
end
end
end
4.2 响应类型 #
elixir
def show(conn, %{"id" => id}) do
user = Accounts.get_user!(id)
render(conn, :show, user: user)
end
def show_json(conn, %{"id" => id}) do
user = Accounts.get_user!(id)
json(conn, %{id: user.id, name: user.name})
end
def show_text(conn, %{"id" => id}) do
user = Accounts.get_user!(id)
text(conn, "User: #{user.name}")
end
五、视图与模板 #
5.1 视图模块 #
elixir
defmodule MyAppWeb.UserHTML do
use MyAppWeb, :html
embed_templates "user_html/*"
def format_name(%{first_name: first, last_name: last}) do
"#{first} #{last}"
end
end
5.2 HEEx模板 #
html
<%# lib/my_app_web/controllers/user_html/index.html.heex %>
<h1>Users</h1>
<ul>
<%= for user <- @users do %>
<li>
<.link navigate={~p"/users/#{user}"}>
<%= user.name %>
</.link>
</li>
<% end %>
</ul>
<.link href={~p"/users/new"}>
New User
</.link>
5.3 组件 #
elixir
defmodule MyAppWeb.CoreComponents do
use Phoenix.Component
attr :title, :string, required: true
attr :class, :string, default: nil
slot :inner_block, required: true
def card(assigns) do
~H"""
<div class={["card", @class]}>
<h2 class="card-title"><%= @title %></h2>
<div class="card-content">
<%= render_slot(@inner_block) %>
</div>
</div>
"""
end
end
六、Plug #
6.1 Plug中间件 #
elixir
defmodule MyAppWeb.Plug.Auth do
import Plug.Conn
def init(opts), do: opts
def call(conn, _opts) do
case get_session(conn, :user_id) do
nil ->
conn
|> put_status(:unauthorized)
|> halt()
user_id ->
assign(conn, :current_user, MyApp.Accounts.get_user!(user_id))
end
end
end
6.2 使用Plug #
elixir
pipeline :protected do
plug MyAppWeb.Plug.Auth
end
scope "/admin", MyAppWeb do
pipe_through [:browser, :protected]
get "/dashboard", AdminController, :dashboard
end
七、总结 #
本章学习了:
| 特性 | 用途 |
|---|---|
| 路由 | 定义URL映射 |
| 控制器 | 处理请求 |
| 视图 | 渲染模板 |
| HEEx | 模板语法 |
| Plug | 中间件 |
准备好学习Ecto了吗?让我们进入下一章。
最后更新:2026-03-27