2 个不稳定版本
0.2.0 | 2020年5月8日 |
---|---|
0.1.0 | 2019年3月13日 |
#8 in #vdom
在 dodrio 中使用
195KB
3.5K SLoC
使用JavaScript实现dodrio
渲染组件。
此crate提供了一个Rust类型JsRender
,它包装了一个具有render
方法的JavaScript对象。JsRender
通过调用包装对象的render
方法来实现dodrio::Render
,该方法返回一个表示为JavaScript值树的JavaScript虚拟DOM。然后,它将此JavaScript值树转换为dodrio
的正常增量分配虚拟DOM表示。
这可能会比直接从Rust方面将虚拟DOM渲染到增量分配器慢得多!此外,JavaScript虚拟DOM的形状有点古怪且不符合常规。请注意,这个crate的存在是为了证明将JavaScript组件集成到dodrio
(它本身也是实验性的)中的概念——因此这个crate肯定有一些粗糙的边缘。
示例
这是一个渲染组件的JavaScript实现
class Greeting {
constructor(who) {
this.who = who;
}
render() {
return {
tagName: "p",
attributes: [
{
name: "class",
value: "greeting",
},
],
listeners: [
{
on: "click",
callback: this.onClick.bind(this),
}
],
children: [
"Hello, ",
{
tagName: "strong",
children: [this.who],
}
],
};
}
async onClick(vdom, event) {
// Be more excited!
this.who += "!";
// Schedule a re-render.
await vdom.render();
console.log("re-rendering finished!");
}
}
这是一个内部使用JS渲染组件的Rust渲染组件
use dodrio::{Node, Render, RenderContext, Vdom};
use dodrio_js_api::JsRender;
use js_sys::Object;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
// Import the JS `Greeting` class.
#[wasm_bindgen(extends = Object)]
#[derive(Clone, Debug)]
type Greeting;
// And the `Greeting` class's constructor.
#[wasm_bindgen(constructor)]
fn new(who: &str) -> Greeting;
}
/// This is our Rust rendering component that wraps the JS rendering component.
pub struct GreetingViaJs {
js: JsRender,
}
impl GreetingViaJs {
/// Create a new `GreetingViaJs`, which will internally create a new JS
/// `Greeting`.
pub fn new(who: &str) -> GreetingViaJs {
let js = JsRender::new(Greeting::new(who));
GreetingViaJs { js }
}
}
/// And finally the `Render` implementation! This adds a `<p>` element and some
/// text around whatever the inner JS `Greeting` component renders.
impl<'a> Render<'a> for GreetingViaJs {
fn render(&self, cx: &mut RenderContext<'a>) -> Node<'a> {
use dodrio::builder::*;
p(&cx)
.children([
text("JavaScript says: "),
self.js.render(cx),
])
.finish()
}
}
依赖项
~6.5–9MB
~173K SLoC