第一个应用 #
一、创建项目 #
1.1 生成项目 #
bash
# 创建新项目
mix phx.new hello
# 进入项目目录
cd hello
# 安装依赖
mix deps.get
# 创建数据库
mix ecto.create
1.2 启动服务器 #
bash
# 启动开发服务器
mix phx.server
# 访问 http://localhost:4000
二、理解请求流程 #
2.1 请求处理流程 #
text
用户请求
│
▼
Endpoint (hello_web/endpoint.ex)
│
▼
Router (hello_web/router.ex)
│
▼
Pipeline (browser)
│
▼
Controller (hello_web/controllers/page_controller.ex)
│
▼
View (hello_web/views/page_view.ex)
│
▼
Template (hello_web/controllers/page_html/index.html.heex)
│
▼
响应返回
2.2 Endpoint入口 #
elixir
defmodule HelloWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :hello
@session_options [
store: :cookie,
key: "_hello_key",
signing_salt: "your_salt"
]
plug Plug.Static,
at: "/",
from: :hello,
gzip: false,
only: HelloWeb.static_paths()
plug Plug.Session, @session_options
plug HelloWeb.Router
end
三、创建第一个页面 #
3.1 添加路由 #
elixir
defmodule HelloWeb.Router do
use HelloWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :protect_from_forgery
plug :put_secure_browser_headers
end
scope "/", HelloWeb do
pipe_through :browser
get "/", PageController, :home
get "/hello", HelloController, :index
get "/hello/:name", HelloController, :show
end
end
3.2 创建控制器 #
elixir
defmodule HelloWeb.HelloController do
use HelloWeb, :controller
def index(conn, _params) do
render(conn, :index)
end
def show(conn, %{"name" => name}) do
render(conn, :show, name: name)
end
end
3.3 创建视图模块 #
elixir
defmodule HelloWeb.HelloHTML do
use HelloWeb, :html
embed_templates "hello_html/*"
end
3.4 创建模板 #
heex
defmodule HelloWeb.HelloHTML do
use HelloWeb, :html
embed_templates "hello_html/*"
end
heex
heex
四、使用布局 #
4.1 应用布局 #
heex
defmodule HelloWeb.Layouts do
use HelloWeb, :html
embed_templates "layouts/*"
end
heex
defmodule HelloWeb.Layouts do
use HelloWeb, :html
embed_templates "layouts/*"
end
4.2 在模板中使用布局内容 #
heex
defmodule HelloWeb.Layouts do
use HelloWeb, :html
embed_templates "layouts/*"
end
五、添加样式 #
5.1 使用CSS #
css
defmodule HelloWeb.Layouts do
use HelloWeb, :html
embed_templates "layouts/*"
end
5.2 使用Tailwind CSS #
heex
defmodule HelloWeb.Layouts do
use HelloWeb, :html
embed_templates "layouts/*"
end
六、处理表单 #
6.1 创建表单页面 #
elixir
defmodule HelloWeb.Router do
scope "/", HelloWeb do
pipe_through :browser
get "/", PageController, :home
get "/greet", GreetController, :new
post "/greet", GreetController, :create
end
end
6.2 创建表单控制器 #
elixir
defmodule HelloWeb.GreetController do
use HelloWeb, :controller
def new(conn, _params) do
render(conn, :new)
end
def create(conn, %{"name" => name}) do
redirect(conn, to: "/hello/#{name}")
end
end
6.3 创建表单模板 #
heex
defmodule HelloWeb.Layouts do
use HelloWeb, :html
embed_templates "layouts/*"
end
七、使用Flash消息 #
7.1 设置Flash消息 #
elixir
defmodule HelloWeb.GreetController do
use HelloWeb, :controller
def create(conn, %{"name" => name}) do
conn
|> put_flash(:info, "Hello, #{name}!")
|> redirect(to: "/hello/#{name}")
end
end
7.2 显示Flash消息 #
heex
defmodule HelloWeb.Layouts do
use HelloWeb, :html
embed_templates "layouts/*"
end
八、JSON响应 #
8.1 创建API路由 #
elixir
defmodule HelloWeb.Router do
pipeline :api do
plug :accepts, ["json"]
end
scope "/api", HelloWeb do
pipe_through :api
get "/users", UserController, :index
get "/users/:id", UserController, :show
end
end
8.2 创建API控制器 #
elixir
defmodule HelloWeb.UserController do
use HelloWeb, :controller
def index(conn, _params) do
users = [
%{id: 1, name: "Alice"},
%{id: 2, name: "Bob"}
]
json(conn, users)
end
def show(conn, %{"id" => id}) do
user = %{id: String.to_integer(id), name: "User #{id}"}
json(conn, user)
end
end
九、错误处理 #
9.1 自定义错误页面 #
elixir
defmodule HelloWeb.ErrorHTML do
use HelloWeb, :html
def render("404.html", _assigns) do
"Page not found"
end
def render("500.html", _assigns) do
"Internal server error"
end
end
9.2 自定义错误模板 #
heex
defmodule HelloWeb.Layouts do
use HelloWeb, :html
embed_templates "layouts/*"
end
heex
defmodule HelloWeb.Layouts do
use HelloWeb, :html
embed_templates "layouts/*"
end
十、项目结构 #
10.1 目录结构 #
text
hello/
├── config/ # 配置文件
│ ├── config.exs
│ ├── dev.exs
│ ├── runtime.exs
│ └── test.exs
├── lib/
│ ├── hello/ # 业务逻辑
│ │ ├── application.ex
│ │ ├── repo.ex
│ │ └── accounts/ # Context
│ └── hello_web/ # Web层
│ ├── controllers/
│ ├── components/
│ ├── endpoint.ex
│ ├── router.ex
│ └── views/
├── priv/
│ └── repo/
│ └── migrations/
├── assets/ # 前端资源
│ ├── css/
│ └── js/
├── test/ # 测试文件
├── mix.exs # 项目配置
└── README.md
10.2 核心文件说明 #
| 文件 | 说明 |
|---|---|
| lib/hello/application.ex | OTP应用定义 |
| lib/hello/repo.ex | Ecto仓库 |
| lib/hello_web/endpoint.ex | HTTP入口 |
| lib/hello_web/router.ex | 路由定义 |
| lib/hello_web/controllers/ | 控制器 |
| lib/hello_web/components/ | 组件 |
| config/ | 配置文件 |
十一、热重载 #
11.1 开发模式热重载 #
Phoenix在开发模式下自动支持热重载:
elixir
config :hello, HelloWeb.Endpoint,
live_reload: [
patterns: [
~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$",
~r"lib/hello_web/(controllers|live|components)/.*(ex|heex)$"
]
]
11.2 修改代码后 #
text
修改控制器或模板后,刷新浏览器即可看到变化
Phoenix会自动重新编译并加载修改的模块
十二、总结 #
12.1 学到的内容 #
| 内容 | 说明 |
|---|---|
| 项目创建 | mix phx.new |
| 路由定义 | Router模块 |
| 控制器 | 处理请求,返回响应 |
| 视图 | 模板渲染辅助 |
| 模板 | HEEx模板语法 |
| 布局 | 应用布局模板 |
| Flash | 临时消息 |
12.2 下一步 #
现在你已经创建了第一个Phoenix应用,接下来让我们深入了解 目录结构,理解Phoenix项目的组织方式!
最后更新:2026-03-28