查看源代码 Phoenix.LiveView.Router (Phoenix LiveView v0.20.17)

为 Phoenix 路由器提供 LiveView 路由。

摘要

函数

获取 LiveView 并与控制器闪存合并。

为一组 LiveView 路由定义一个 LiveView 会话。

函数

链接到此函数

fetch_live_flash(conn, opts \\ [])

查看源代码

获取 LiveView 并与控制器闪存合并。

替换由 Phoenix.Router 使用的默认 :fetch_flash 插件。

示例

defmodule MyAppWeb.Router do
  use LiveGenWeb, :router
  import Phoenix.LiveView.Router

  pipeline :browser do
    ...
    plug :fetch_live_flash
  end
  ...
end
链接到此宏

live(path, live_view, action \\ nil, opts \\ [])

查看源代码 (宏)

定义 LiveView 路由。

LiveView 可以通过使用带有路径和 LiveView 名称的 live 宏来路由。

live "/thermostat", ThermostatLive

默认情况下,您可以使用 live_path 助手生成到此 LiveView 的路由。

live_path(@socket, ThermostatLive)

HTTP 请求

live/4 宏定义的路由响应的 HTTP 请求方法是 GET

操作和实时导航

LiveView 通常具有多个状态和多个 URL。例如,您可能有一个 LiveView 列出您的 Web 应用程序上的所有文章。对于每篇文章,都有一个“编辑”按钮,当按下该按钮时,会在同一页面上打开一个模态来编辑文章。在这些情况下,最佳做法是使用实时导航,因此当您点击编辑时,URL 更改为“/articles/1/edit”,即使您仍然在同一个 LiveView 中。同样,您可能还想显示一个“新建”按钮,该按钮会打开一个模态以创建新条目,您希望这在 URL 中反映为“/articles/new”。

为了更轻松地识别您的 LiveView 所处的当前“操作”,您也可以在定义 LiveView 时传递操作选项。

live "/articles", ArticleLive.Index, :index
live "/articles/new", ArticleLive.Index, :new
live "/articles/:id/edit", ArticleLive.Index, :edit

当给出操作时,生成的路由助手以 LiveView 本身命名(与控制器相同)。对于上面的示例,我们将有

article_index_path(@socket, :index)
article_index_path(@socket, :new)
article_index_path(@socket, :edit, 123)

当前操作将始终作为 @live_action 赋值在 LiveView 中可用,可用于呈现 LiveComponent。

<%= if @live_action == :new do %>
  <.live_component module={MyAppWeb.ArticleLive.FormComponent} id="form" />
<% end %>

或可用于显示或隐藏模板的某些部分。

<%= if @live_action == :edit do %>
  <%= render("form.html", user: @user) %>
<% end %>

请注意,如果在路由定义中没有给出任何操作,则 @live_action 将为 nil

选项

  • :container - 用于 LiveView 容器的 HTML 标签和 DOM 属性的可选元组。例如:{:li, style: "color: blue;"}。有关更多信息和示例,请参阅 Phoenix.Component.live_render/3

  • :as - 可选地配置命名助手。在使用没有操作的 LiveView 时默认为 :live,或者在使用操作时默认为 LiveView 名称。

  • :metadata - 用于遥测事件和路由信息的可选馈送元数据的映射,例如:%{route_name: :foo, access: :user}。可以使用 Phoenix.Router.route_info/4handle_params 回调中的 uri 调用此数据。这可用于自定义可能从不同路由调用的 LiveView。

  • :private - 要放入 *插件连接* 的可选私有数据映射,例如:%{route_name: :foo, access: :user}。数据将在插件函数中的 conn.private 中可用。

示例

defmodule MyApp.Router
  use Phoenix.Router
  import Phoenix.LiveView.Router

  scope "/", MyApp do
    pipe_through [:browser]

    live "/thermostat", ThermostatLive
    live "/clock", ClockLive
    live "/dashboard", DashboardLive, container: {:main, class: "row"}
  end
end

iex> MyApp.Router.Helpers.live_path(MyApp.Endpoint, MyApp.ThermostatLive)
"/thermostat"
链接到此宏

live_session(name, opts \\ [], list)

查看源代码 (宏)

为一组 LiveView 路由定义一个 LiveView 会话。

live_session/3 允许使用 live/4 定义的路由支持来自客户端的 live_redirect,并通过现有的 Websocket 连接进行纯粹的导航。这允许在路由器中定义的 LiveView 路由安装新的根 LiveView,而无需对服务器进行额外的 HTTP 请求。出于向后兼容性的原因,在任何 LiveView 会话之外定义的所有 LiveView 路由都被视为单个未命名的 LiveView 会话的一部分。

安全注意事项

在常规 Web 应用程序中,我们对每个请求执行身份验证和授权检查。鉴于 LiveView 从常规 HTTP 请求开始,它们通过插件与常规请求共享身份验证逻辑。一旦用户经过身份验证,我们通常会在 mount 回调上验证会话。授权规则通常发生在 mount 上(例如,用户是否有权查看此页面?),以及在 handle_event 上(用户是否有权删除此项目?)。在安装时执行授权很重要,因为 live_redirect *不会经过插件管道*。

live_session 可用于在 LiveView 组之间划定界限。在 live_session 之间进行重定向将始终强制进行完整的页面重新加载并建立一个全新的 LiveView 连接。当 LiveView 需要不同的身份验证策略或只是使用不同的根布局时,这很有用(因为根布局不会在 LiveView 重定向之间更新)。

阅读我们关于安全模型的指南,以详细了解身份验证、授权等方面的详细描述和一般提示。

live_sessionforward

live_session 目前不适用于 forward。LiveView 期望您的 live 路由始终直接定义在应用程序的主路由器中。

live_sessionscope

使用 Phoenix.Router.scope/2 设置的别名不会扩展到 live_session 参数中。您必须使用完整的模块名称。

选项

  • :session - 要与 LiveView 会话合并的可选额外会话映射或 MFA 元组。例如,%{"admin" => true}{MyMod, :session, []}。对于 MFA,函数将被调用,并且 Plug.Conn 结构将被附加到参数列表的开头。

  • :root_layout - 用于初始 HTTP 呈现的可选根布局元组,以覆盖路由器中设置的任何现有根布局。

  • :on_mount - 要附加到 *会话中每个 LiveView 的安装生命周期* 的可选钩子列表。请参阅 Phoenix.LiveView.on_mount/1。也接受单个值。

  • :layout - LiveView 将在其中呈现的可选布局。设置此选项将覆盖通过 use Phoenix.LiveView 设置的布局。此选项可以在 LiveView 中通过从安装回调返回 {:ok, socket, layout: ...} 来覆盖。

示例

scope "/", MyAppWeb do
  pipe_through :browser

  live_session :default do
    live "/feed", FeedLive, :index
    live "/status", StatusLive, :index
    live "/status/:id", StatusLive, :show
  end

  live_session :admin, on_mount: MyAppWeb.AdminLiveAuth do
    live "/admin", AdminDashboardLive, :index
    live "/admin/posts", AdminPostLive, :index
  end
end

在上面的示例中,我们有两个 LiveView 会话。不同会话中的 LiveView 之间的实时导航是不可能的,并且始终需要完整的页面重新加载。在上面的示例中这一点很重要,因为 :admin LiveView 会话具有身份验证要求,由 on_mount: MyAppWeb.AdminLiveAuth 定义,而其他 LiveView 则没有。

如果您同时具有常规 HTTP 路由(通过 get、post 等)和 live 路由,则您需要在这两者中执行相同的身份验证和授权规则。例如,如果您要将 get "/admin/health" 入口点添加到上面的 :admin LiveView 会话中,那么您必须创建自己的插件,该插件执行与 MyAppWeb.AdminLiveAuth 相同的身份验证和授权规则,然后通过它进行管道传输。

live_session :admin, on_mount: MyAppWeb.AdminLiveAuth do
  scope "/" do
    # Regular routes
    pipe_through [MyAppWeb.AdminPlugAuth]
    get "/admin/health", AdminHealthController, :index

    # Live routes
    live "/admin", AdminDashboardLive, :index
    live "/admin/posts", AdminPostLive, :index
  end
end

反之亦然,如果您有常规的 http 路由并且您想添加自己的 live 路由,则在 pipe_through 中列出的插件执行的相同身份验证和授权检查必须移植到 LiveView 并在 on_mount 钩子中执行。