底层库的内部细节

潜藏在 html! 宏之下

html!宏会将以自定义 HTML 格式的语法编写的代码转换为有效的 Rust 代码。尽管可以不使用此宏来开发 Yew 应用程序,但不推荐这么做。该宏生成的代码使用的是 Yew 公共库的 API,如果你愿意,可以直接使用相应的 API 作为替代。另外请注意,某些方法是故意不写入文档的,需要多加留意,避免意外使用。 yew-macro每次更新,生成的代码将更加高效,当其存在重大修改时,只需对html!的语法进行少量(如果有的话)修正就能应对这个情况。

因为html!宏允许您通过声明的方式来进行样式的编写,您的 UI 布局代码将与在页面上生成的 HTML 紧密匹配。随着您的应用程序变得更具交互性并且代码库越来越大,此功能会变得越来越有用。无需手动编写所有代码来操作 DOM,宏会为您处理好这些。

使用html!宏给人的感觉像是魔术。如果您对它的工作方式感到好奇,请尝试扩展html!程序中的宏调用。有一个有用的命令,叫cargo expand ,它使您可以查看 Rust 宏的扩展。 由于cargo expand还未附带在cargo中,如果尚未安装,需要先运行cargo install cargo-expand

请注意,在查看扩展的宏代码时,您可能会遇到异常冗长的代码。因为生成的代码有时可能会与应用程序中的其他代码冲突。为了防止出现问题,请保持proc_macro 的“卫生”。以下是一些示例:

  1. 使用::yew::<module> 而不是 yew::<module> 来保证对 Yew 包的正确引用。这也是为什么呼吁使用::alloc::vec::Vec::new()来代替Vec::new()调用。
  2. 为了避免潜在的 trait 方法名称冲突,使用<Type as Trait>来确保我们使用的是正确的 trait。

什么是虚拟 DOM?

DOM(“文档对象模型”)是 HTML 内容的表示,由您的网页的浏览器管理。 “虚拟” DOM 只是保存在应用程序内存中的 DOM 的副本。管理虚拟 DOM 会导致更高的内存开销,但可以通过避免或延迟使用浏览器 API 来实现批处理和更快的读取。

在内存中拥有一份 DOM 副本对于使用声明式 UI 的库非常有帮助,并且可以促进人们使用它们 。不需要特定的代码来描述应该如何修改 DOM 以响应用户事件,该库可以使用 DOM “diffing”的通用方法。当 Yew 组件更新并想要更改其呈现方式时,Yew 库将构建虚拟 DOM 的第二个副本,并直接与反映当前屏幕内容的虚拟 DOM 进行比较。两者之间的差异会做为增量更新的依据,并通过浏览器 API 批量操作。应用更新后,旧的虚拟 DOM 副本将被丢弃,而新副本会保存下来以供将来进行差异检查。

这种“diff”算法可以随着时间的推移进行优化,以提高复杂应用程序的性能。由于 Yew 应用程序是使用 WebAssembly 运行的,我们相信随着未来的算法愈加复杂, Yew 会在性能方面更具优势。

Yew 的虚拟 DOM 与浏览器 DOM 并不是完全对应的。它还包括用于组织 DOM 元素的“列表”和“组件”。列表可以只是元素的有序列表,但也可以更强大。通过使用“key”标注每个列表元素,应用程序开发人员可以帮助 Yew 进行额外的优化,以确保当列表发生变化时,计算差异更新的工作量最少。同样,组件提供自定义逻辑来指示是否需要重新渲染以帮助提高性能。

Yew 调度程序和组件范围的事件循环

对文档做出贡献–解释yew::scheduleryew::html::scope的底层是如何工作的

进一步阅读: