#virtual-dom #js #vdom #javascript

dodrio-js-api

JavaScript 实现Dodrio渲染组件的API

2 个不稳定版本

0.2.0 2020年5月8日
0.1.0 2019年3月13日

#8 in #vdom


dodrio 中使用

MPL-2.0 许可证

195KB
3.5K SLoC

Rust 3K SLoC // 0.1% comments JavaScript 359 SLoC // 0.1% comments Shell 12 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