#elements #component #web #create #traits #shadow #dom

custom-elements

一个用于创建 Rust/WASM 网页组件/自定义元素的 CustomElement 特性,无需编写任何 JavaScript 即可轻松实现。

3 个不稳定版本

0.2.1 2024年1月27日
0.2.0 2021年8月21日
0.1.0 2021年8月20日

1107网页编程

Download history 20/week @ 2024-03-09 7/week @ 2024-03-16 8/week @ 2024-03-23 61/week @ 2024-03-30 18/week @ 2024-04-06 14/week @ 2024-04-13 1/week @ 2024-04-20 13/week @ 2024-04-27 14/week @ 2024-05-04 15/week @ 2024-05-11 8/week @ 2024-05-18 14/week @ 2024-05-25 33/week @ 2024-06-01 15/week @ 2024-06-08 11/week @ 2024-06-15 4/week @ 2024-06-22

66 每月下载量

Apache-2.0/MIT

21KB
210

crates.io docs.rs

一个框架无关的 CustomElement 特性,可以轻松地创建 Rust/WASM 网页组件/自定义元素,无需编写任何 JavaScript。

概述

Web Components 标准创建了一个浏览器功能,允许您创建可重用组件,称为 Custom Elements。(人们通常使用“Web Components”这个标签来特指 Custom Elements;Web Components 标准还包括 Shadow DOM 和 HTML 模板。)

虽然 web_sys 提供了浏览器的 CustomElementRegistry 接口,但使用起来可能很困难。创建一个 Custom Element 需要调用 customElements.define() 并传入一个扩展了 HTMLElement 的 ES2015 类,这目前从 Rust 中无法直接完成。

此 crate 提供了一个 CustomElement 特性,当实现它时,允许您将任何 Rust 结构封装为可重用的网页组件,无需编写任何 JavaScript。理论上它应该可以与任何 Rust 前端框架一起使用;examples 目录包含了 Yew 和纯 Rust/WASM 组件的示例。

impl CustomElement for MyWebComponent {
  fn inject_children(&mut self, this: &HtmlElement) {
      inject_style(&this, "p { color: green; }");
      let node = self.view();
      this.append_child(&node).unwrap_throw();
  }

  fn observed_attributes() -> &'static [&'static str] {
      &["name"]
  }

  fn attribute_changed_callback(
      &mut self,
      _this: &HtmlElement,
      name: String,
      _old_value: Option<String>,
      new_value: Option<String>,
  ) {
      if name == "name" {
          /* do something... */
      }
  }

  fn connected_callback(&mut self, _this: &HtmlElement) {
      log("connected");
  }

  fn disconnected_callback(&mut self, _this: &HtmlElement) {
      log("disconnected");
  }

  fn adopted_callback(&mut self, _this: &HtmlElement) {
      log("adopted");
  }
}

#[wasm_bindgen]
pub fn define_custom_elements() {
    MyWebComponent::define("my-component");
}

Shadow DOM

默认情况下,这些自定义元素使用 Shadow DOM(在“打开”模式下)来封装元素的风格和内容。您可以通过实现 shadow 方法并返回 false 来简单地覆盖此选择。

fn shadow() -> bool {
    false
}

生命周期方法

您可以实现每个自定义元素的生命周期回调。每个回调都会传入正在实现的特性和自定义元素的 HtmlElement


fn connected_callback(&mut self, this: &HtmlElement) {
    log("connected");
}

fn disconnected_callback(&mut self, this: &HtmlElement) {
    log("disconnected");
}

fn adopted_callback(&mut self, this: &HtmlElement) {
    log("adopted");
}

fn attribute_changed_callback(
    &mut self,
    this: &HtmlElement,
    name: String,
    old_value: Option<String>,
    new_value: Option<String>,
) {
    if name == "name" {
        // do something
    }
}

使用 Rust 框架

实现 CustomElement 至少需要一种将子元素注入自定义元素的方法。通常,通过 attribute_changed_callback 响应其属性的更改也是很有帮助的。根据框架的不同,这些可能更容易或更难实现;特别是对于 Elm 风格的框架,您可能需要创建一个包装器,该包装器拥有某种方式来更新应用程序的状态。

请参阅 Yew 示例,了解如何与框架的 API 一起工作。

自定义内置元素

自定义元素可以是自主的(<my-component></my-component>)或自定义内置元素(<p is="my-paragraph-component"></p>). 这个 crate 提供了通过 superclass` 方法创建自定义内置元素的 支持

资源

这是一个针对 Custom Elements API 的相当简单的包装。以下 MDN 源应该能给你足够的信息来开始创建自定义元素

运行示例

示例使用了 wasm-pack 和一个简单的 Python 服务器。你应该能够通过以下命令运行它们

./build.sh && ./runserver

依赖项

~6.5–8.5MB
~169K SLoC