rsx 与组件
这一部分讲用户写下的两样东西:rsx! 和组件函数。源码分在三处:packages/rsx/src(约 5.7k 行,rsx! 的解析和代码生成,template_body.rs、assign_dyn_ids.rs、element.rs、attribute.rs、ifmt.rs)、packages/core-macro/src(约 3.3k 行,#[component] 和 Props derive)、packages/core/src 里的 nodes.rs、properties.rs、render_error.rs(运行期的数据结构)。
dioxus 和 React 一样每次更新都整个重跑组件函数、得到一棵新的虚拟树,区别在 rsx! 在编译期就把树里不会变的部分切出去,印成一个 static 的模板;组件每次只新建动态部分。这一部分讲到组件函数返回一个 VNode 为止,新旧两个 VNode 怎么比、指令怎么发出去,在 03 VirtualDom 内核。
- rsx! 展开成什么:
rsx!解析成CallBody,根、组件 children、for循环体、if的每个分支各是一个模板;只有不含洞的字符串字面量能进模板,整数、布尔、const、花括号表达式都是动态的;动态部分按深度优先编号,路径的第一个数是根的下标;release 下是static Template,debug 下路径在运行期算、每个洞多格式化一次,给热重载用。 - Template 与 VNode:
VNode是 16 字节的Rc加挂载号,相等只比指针;Template是三个静态切片,release 按指针比、debug 按值比;DynamicNode的四种变体,AttributeValue的七种值;Element就是Result<VNode, RenderError>;IntoDynNode决定什么能放进{}。 - #[component] 与 Props:
#[component]生成Props结构体和类型状态 builder;memoize相等就跳过子组件;实验数出每种 props 的重跑次数:普通值按值比,闭包和children按指针比、每次都重跑,ReadSignal跳过子组件但通知订阅者。
flowchart TB src["rsx 宏调用"] --> tpl["static Template"] src --> dyn["动态部分 按序号"] tpl --> vnode["VNode"] dyn --> vnode comp["component 函数"] --> props["Props 与 builder"] props --> vcomp["DynamicNode Component"] vcomp --> dyn vnode --> diffnode["03 diff"] props --> memo["memoize"] memo --> diffnode
💬 关联讨论
发起讨论加载中...