view
topcoat-view 加上它的 grammar 一共 1.8 万行,是请求主线的最后一段:page 返回的 impl View 怎么变成一段段 HTML。两章:
- view! 展开成什么:
cargo expand两个组件逐段对照;Emitter的两个阶段和JoinView;ViewBuffer里不超过 16 字节、无需 Drop 的指令和一个带返回栈的解释器;按位置转义的实测输出(href不检查协议,<script>里的插值和字面量都会被实体化);hoist把 signal 注释放到 DOCTYPE 之前,无头 Chrome 里compatMode仍是CSS1Compat;for不写#[key]时的 panic 原文。 - 组件、并发渲染与流式:
View的两个方法与 yielder;三个组件在同一个 tokio 任务里并发(实测同一个任务 id,总耗时 309 毫秒);suspense的四个状态与Wait模式;error_boundary在首屏前后的两种行为;live!/emit!的分块时间线;递归组件与BoxView。
flowchart TB macro["view! 展开:两个阶段"] --> buf["ViewBuffer:指令块"] buf --> render["Renderer:执行指令、转义"] macro --> join["JoinView:同一任务里并发"] join --> stream["suspense、error_boundary、live!:poll_swap 追加"] stream --> body["02 router 的 ViewBody:template + swap 脚本"]
| 文件 | 行数(含测试) | 管什么 | 章 |
|---|---|---|---|
view-grammar/src/view.rs、view/ | 约 3 800 | view! 的语法树与 HIR、两个阶段的代码生成 | 1 |
buffer.rs、buffer/ | 约 2 000 | 指令、常量区、解释器 | 1 |
html.rs、html/ | 约 3 000 | 转义、属性、类名 | 1 |
hoist.rs | 578 | hoist、HoistView | 1 |
view.rs、internal/ | 约 1 850 | View trait、JoinView、LoopView、SuspenseView、LiveView、ErrorBoundaryView、yielder | 2 |
💬 关联讨论
发起讨论加载中...