9 个不稳定版本 (3 个破坏性更新)
| 0.3.2 | 2024 年 6 月 2 日 |
|---|---|
| 0.3.1 | 2024 年 6 月 1 日 |
| 0.3.0 | 2024 年 5 月 31 日 |
| 0.2.2 | 2024 年 5 月 25 日 |
| 0.0.4 | 2024 年 5 月 12 日 |
#1056 在 WebAssembly
每月 107 次下载
在 dioxus-web-component 中使用
49KB
1K SLoC
dioxus-web-component-macro
提供一个处理宏来构建 Dioxus 网络组件。
示例
该宏替换了 Dioxus 的 #[component] 宏。
use dioxus::prelude::*;
use dioxus_web_component::{web_component, DioxusWebComponent};
use wasm_bindgen::prelude::*;
#[web_component]
fn MyWebComponent(
attr: Option<String>,
event: EventHandler<i64>,
) -> Element {
rsx ! {
div {
// ...
}
}
}
#[wasm_bindgen(main)]
pub fn main() {
// Register the web component (aka custom element)
register_my_web_component();
}
<!-- include the script generated with wasm-pack -->
<script type="module" src="my-web-component.js"></script>
<!-- in the body -->
<my-web-component attr="plop"></my-web-component>
使用方法
标签
自定义元素标签由组件名称构建。
默认情况下,标签是名称的短横线版本。例如,MyWebComponent 变为 my-web-component。
您可以使用 tag 属性更改默认行为。
use dioxus::prelude::*;
use dioxus_web_component::{web_component, DioxusWebComponent};
#[web_component(tag = "plop-component")]
fn MyWebComponent(
// ...
) -> Element { todo!() }
<!-- in the body -->
<plop-component></plop-component>
ℹ️ 信息:自定义元素标签名称有约束。宏会为您检查标签的有效性。请参阅 MDN - 有效的自定义元素名称
样式
您可以使用 style 属性提供网络组件样式。
use dioxus::prelude::*;
use dioxus_web_component::{web_component, InjectedStyle};
#[web_component(
tag = "plop-greeting",
style = InjectedStyle::css(include_str!("./style.css"))
)]
fn Greeting(
// ...
) -> Element {
todo!()
}
dioxus_web_component::InjectedStyle 可以是包含在 HTML <style>...</style> 元素中的原始 CSS,或指向外部样式表的链接,或 InjectedStyle 样式的列表。
⚠️ 警告:网络组件被包装在一个带有 dioxus CSS 类的 HTML div 中。
组件参数
您的组件的每个参数都应该是一个属性、一个属性或一个事件。请注意,参数可以是属性和属性的组合。
处理宏试图通过查看其类型来检测参数的类型。如果类型以 EventHandler 开头,则它被期望是一个事件。但是,这种检测并不可靠,因此您可能需要添加一个注释来纠正此行为。
如果需要自定义行为,也需要这些注释。
属性
属性类似于 href HTML 元素。
您可以使用#[attribute]注解将参数强制转换为属性。
当属性值发生变化时,dioxus组件将被渲染。
属性的HTML值是一个String,因此您应该能够将该字符串解析为目标类型。
属性name
属性名默认是参数名的短横线命名法。您可以使用#[attribute(name = "my-custom-name")]选择另一个名称。
属性option
属性可以是可选的或不选的。宏尝试通过类型名称自动检测它。但是检测并不可靠,所以如果需要,您可以使用#[attribute(option = true)]来修复检测。
属性initial
属性需要有一个初始值。如果没有提供HTML属性或属性被删除时,将使用此值。
默认情况下,我们期望属性类型实现std::default::Default。如果不是这种情况,或者您想为属性使用其他值,您可以使用#[attribute(initial = String::from("World"))]提供您的默认表达式。
请注意,即使T没有实现自己的Default,Option<T>也会使用Default的None值。
属性parse
HTML属性是字符串和可选的,因此我们需要将属性值转换为组件参数类型。
宏使用std::str::parse方法。这意味着目标类型需要实现std::str::FromStr特性。
在发生错误的情况下,使用初始值(见下文)。
如果您想更改此行为,可以提供您的解析表达式。
如果参数类型是可选的,此代码中使用解析表达式:let value = new_value.and_then(#parse);. 如果类型不是可选的,代码如下:let value = new_value.and_then(#parse).unwrap_or_else(|| #initial);.
解析表达式的预期类型是 FnOnce(String) -> Option<T>. 默认表达式是 |value| value.parse().ok().
例如,如果你有一个类型为 bool 的参数 required,并且你希望无论属性的任何内容,如果属性存在,值都为 true,你可以使用 #[attribute(parse = |s| !s.is_empty() )].
属性
在Rust代码的Rust端,属性像属性一样工作。属性不能通过纯HTML访问,你需要JavaScript来获取/设置属性。
除了 String 表示形式,你需要能够将Rust类型转换为JavaScript类型(这里是一个 wasm_bindgen::JsValue)。对于设置器,你需要进行相反的转换。
属性name
默认情况下,属性名是参数名的camelCase形式。你可以使用 #[property(name = "valueAsDate")] 选择另一个名称。
属性 readonly
如果设置为 true,它将避免从JavaScript端设置属性。默认情况下会生成获取器和设置器。
属性initial
属性需要有一个初始值。此值在组件初始化时使用。
默认情况下,我们期望属性类型实现 std::default::Default。如果不是这种情况,或者您想为您的属性使用另一个值,您可以使用以下代码提供默认表达式:#[property(initial = String::from("World"))].
属性 try_into_js
对于获取器,属性值应转换为 wasm_bindgen::JsValue。默认情况下,我们使用 std::convert::TryInto 实现方式。
注意,有多种方式来实现 TryInto<JsValue>,例如使用 impl TryFrom<T> for JsValue 或甚至 impl From<T> for JsValue。请参阅 Rust TryInto。
您可以使用 try_into_js 属性提供您的自定义转换到 JsValue。解析表达式的预期类型是 FnOnce(T) -> Result<JsValue, _>。注意,我们并不关心错误类型,因为错误情况被忽略,并返回 undefined。
默认表达式是 |value| value.try_into()。
将自定义类型(包装了 bool)转换为示例
// ...
#[property(
try_into_js = |prop| {
let js_value = if prop.0 {
JsValue::TRUE
} else {
JsValue::FALSE
};
Ok::<_, Infallible>(js_value)
},
)]
prop2: MyProp,
// ...
#[derive(Clone, PartialEq, Default)]
struct MyProp(bool);
但在那种情况下,建议的方式是实现 From<MyProp> for JsValue。
属性 try_from_js
对于设置器,属性值应从 wasm_bindgen::JsValue 转换。默认情况下,我们使用 std::convert::TryInto 实现方式。
请注意,实现TryInto<T>有许多方法,例如使用impl TryFrom<JsValue> for T或甚至impl From<JsValue> for T。参见Rust TryInto。
您可以使用try_from_js属性提供您的自定义从JsValue的转换。解析表达式的期望类型是FnOnce(JsValue) -> Result<T, _>。请注意,我们不关心错误类型,因为错误情况被忽略。
默认表达式是 |value| value.try_into()。
将自定义类型(包装了 bool)转换为示例
// ...
#[property(
try_from_js= |value| Ok::<_, Infallible>(MyProp(value.is_truthy())),
)]
prop2: MyProp,
// ...
#[derive(Clone, PartialEq, Default)]
struct MyProp(bool);
但在那种情况下,推荐的方式是实现From<JsValue> for MyProp。
事件
Web组件可以发送自定义事件。如果组件参数的类型是EventHandler,则参数被检测为事件。由于这种检测并不可靠,您可以使用#[event]注解强制参数为事件。
自定义事件细节对应于Dioxus EventHandler的泛型类型。
⚠️ 重要:事件类型需要实现Into<JsValue>并且是'static(不包含任何引用)。
您可能需要手动实现它。您可以使用serde-wasm-bindgen、gloo_utils::format::JsValueSerdeExt、wasm_bindgen::UnwrapThrowExt来实现Into<JsValue>特质。
事件 name
HTML事件名称通过删除on_(或on)前缀并将名称转换为短横线命名法从参数名称检测得到。您可以通过name属性选择您的值,例如使用#[event]]来派发一个build事件。
事件 no_bubble
默认情况下,事件会冒泡到DOM中。您可以使用以下代码避免冒泡:#[event(no_bubble = true)]。
事件 no_cancel
默认情况下,事件是可取消的。您可以使用以下代码避免冒泡:#[event(no_cancel = true)]。
依赖关系
~0.6–1.1MB
~25K SLoC