查看源代码 实时布局

从 Phoenix v1.7 开始,您的应用程序由两个布局组成

  • 根布局 - 这是 LiveView 和普通视图使用的布局。该布局通常包含 <html> 定义以及头部和主体标签。在根布局中定义的任何内容都将保持不变,即使您在 LiveView 之间进行实时导航也是如此。根布局通常在路由器上使用 put_root_layout 声明,并在您的布局文件夹中定义为 "root.html.heex"

  • 应用程序布局 - 这是默认的应用程序布局,它在普通 HTTP 请求和 LiveView 上呈现。它默认为 "app.html.heex"

总体而言,这些布局位于 components/layouts 中,并嵌入在 MyAppWeb.Layouts 中。

所有布局都必须调用 <%= @inner_content %> 以注入由布局呈现的内容。

根布局

"root" 布局仅在初始请求时呈现,因此它可以访问 @conn 赋值。根布局通常在您的路由器中定义

plug :put_root_layout, html: {MyAppWeb.Layouts, :root}

根布局也可以通过您的路由器中的 :root_layout 选项来设置,方法是通过 Phoenix.LiveView.Router.live_session/2.

应用程序布局

"app.html.heex" 布局使用 @conn@socket 呈现。控制器和 LiveView 都明确定义了它们将使用的默认布局。请参阅您的 MyAppWeb 中的 def controllerdef live_view 定义,以了解它是如何包含的。

对于 LiveView,默认布局可以通过两种不同的方式来覆盖,以实现灵活性

  1. Phoenix.LiveView.Router.live_session/2 中设置的 :layout 选项将覆盖通过 use Phoenix.LiveView 给出的 :layout 选项

  2. 通过 {:ok, socket, layout: ...} 在 mount 上返回的 :layout 选项将覆盖任何先前设置的布局选项

LiveView 本身将在布局内渲染,并由 :container 标签包裹。

更新文档标题

由于 Plug 管道中的根布局是在 LiveView 之外渲染的,因此其内容无法动态更改。唯一的例外是 HTML 文档的 <title>。Phoenix LiveView 对 @page_title 赋值进行了特殊处理,以便允许动态更新页面标题,这在使用实时导航或使用通知对浏览器标签进行注释时非常有用。例如,要更新浏览器标题栏中的用户通知计数,首先在 mount 上设置 page_title 赋值

def mount(_params, _session, socket) do
  socket = assign(socket, page_title: "Latest Posts")
  {:ok, socket}
end

然后在根布局中访问 @page_title

<title><%= @page_title %></title>

您还可以使用 Phoenix.Component.live_title/1 组件来支持在渲染和后续更新时自动添加页面标题的前缀和后缀

<Phoenix.Component.live_title prefix="MyApp  ">
  <%= assigns[:page_title] || "Welcome" %>
</Phoenix.Component.live_title>

虽然根布局不会由 LiveView 更新,但只需分配给 page_title,LiveView 就知道您希望更新标题

def handle_info({:new_messages, count}, socket) do
  {:noreply, assign(socket, page_title: "Latest Posts (#{count} new)")}
end

注意:如果您发现需要动态修补基本布局的其他部分,例如在实时导航期间将新脚本或样式注入 <head>则应改用常规的非实时页面导航。分配 @page_title 会直接更新 document.title,因此无法用于更新基本布局的任何其他部分。