渲染生命周期

理解 Nex 的渲染生命周期是构建高效、无状态感应用的基石。Nex 的渲染流程非常直观,主要分为两个阶段。

1. 初始渲染 (Full Page Load)

当你通过浏览器地址栏直接访问一个 URL(GET 请求)时,Nex 会执行以下流程:

  1. 路由匹配:根据文件系统路由找到对应的页面模块。
  2. 生成 Page ID:框架为本次访问生成一个唯一的 page_id
  3. 执行 mount(params)
    • 接收 URL 参数和查询参数。
    • 你在此处初始化数据(如从数据库读取)。
    • 返回 assigns Map。
  4. 执行 render(assigns)
    • 使用 assigns 渲染 HEEx 模板。
  5. 注入布局 (Layout)
    • 将渲染结果作为 @inner_content 传递给 src/layouts.ex
    • 自动化注入:在 </body> 标签前自动注入包含 CSRF Token 和 Page ID 的脚本。
  6. 响应客户端:返回完整的 HTML 文档。

2. 异步交互 (Action Update)

当你通过 HTMX 发起请求(如 hx-post)时,生命周期会发生变化:

  1. Action 匹配:根据 URL 路径或 Referer 找到目标 Action 函数。
  2. 执行 Action
    • 跳过 mount:为了性能和局部性,Action 不会重新执行页面的 mount
    • 接收请求参数。
    • 返回 HTML 片段或控制指令(如 {:refresh})。
  3. 局部更新
    • HTMX 接收到响应后,根据 hx-target 仅更新页面的一部分。
    • 状态保持:虽然 mount 没运行,但你可以通过 Nex.Store 读取之前存储的状态。

3. 页面刷新 = 状态重置

这是 Nex 架构中最重要的设计决策之一:

  • 全页刷新 (F5):浏览器丢弃当前所有状态,Nex 发起新的 GET 请求,生成全新的 Page ID
  • 后果:由于 Nex.Store 的状态是绑定在 page_id 上的,旧的状态将无法访问(并在随后被 TTL 清理)。
  • 设计初衷:确保 Web 应用的行为与用户的直觉一致——“刷新页面即回到初始状态”,避免了复杂的脏数据清理问题。

总结

特性 初始渲染 (GET) Action 交互 (POST/…)
执行 mount
生成 Page ID 新建 沿用
Layout 包裹 否 (仅返回片段)
状态读取 初始状态 可读取 Store 中的累积状态