5 个不稳定版本
0.3.0 | 2022 年 9 月 17 日 |
---|---|
0.2.2 | 2022 年 9 月 17 日 |
0.2.1 | 2022 年 9 月 17 日 |
0.2.0 | 2022 年 9 月 17 日 |
0.1.0 | 2022 年 9 月 17 日 |
#26 在 #rsx
76 每月下载次数
在 tide-jsx 中使用
23KB
533 行
tide-jsx
为了将简单的 HTML 片段渲染成 String
,使用 rsx!
宏生成组件树,并在其上调用 render
use tide_jsx::{rsx, Render};
let tree = rsx! {
<div>
<h1>{"Hello!"}</h1>
<p>{"Hello world!"}</p>
</div>
};
assert_eq!(tree.render(), "<div><h1>Hello!</h1><p>Hello world!</p></div>");
因为这很常见,还有一个名为 html!
的宏,它调用 rsx!
生成组件树,然后调用 render
。大多数情况下,您会使用 rsx!
宏来组合任意组件,只有在需要字符串输出时(例如发送响应或生成 Markdown 文件)才调用 html!
。
在 Render 中,使用 render::html_escaping
模块对属性和普通字符串进行转义。为了使用未转义值,以便可以安全地插入原始 HTML,请将字符串放在 raw!
宏周围
use tide_jsx::{html, raw};
let tree = html! {
<div>
<p>{"<Hello />"}</p>
<p>{raw!("<Hello />")}</p>
</div>
};
assert_eq!(tree, "<div><p><Hello /></p><p><Hello /></p></div>");
自定义组件
Render 的最大能力是提供类型安全以及自定义可渲染组件。引入新组件就像定义一个返回 Render
值的函数一样简单。
要从其他组件或 HTML 节点构建组件,可以使用 rsx!
宏,该宏生成 Render
组件树
use tide_jsx::{component, rsx, html};
#[component]
fn Heading<'title>(title: &'title str) {
rsx! { <h1 class={"title"}>{title}</h1> }
}
let rendered_html = html! {
<Heading title={"Hello world!"} />
};
assert_eq!(rendered_html, r#"<h1 class="title">Hello world!</h1>"#);
如果您仔细观察,会发现函数 Heading
是
- 以大写声明。在下面,它生成一个具有相同名称的结构体,并在其上实现
Render
特性。 - 没有返回类型。这是因为为了性能原因,所有内容都写入到写入器中。
可见性与组件库
通常情况下,你可能会想在项目树中的其他位置存储你的组件,而不仅仅是你在工作的模块中(如果不在完全不同的模块中!)。在这些情况下,应用于定义你的组件的函数的可见性将向下传播到该结构体的所有字段。
例如,如果我们在上面的Heading组件前添加“pub”
#[component]
pub fn Heading<'title>(title: &'title str) {
rsx! { <h1 class={"title"}>{title}</h1> }
}
...生成的结构体可能看起来像...
pub struct Heading {
pub title: &'title str
}
从安全角度考虑,在构建你的库时理解这一点非常重要。
完整示例
use render::html::HTML5Doctype;
use render::{component, rsx, html, Render};
#[component]
fn Page<'a, Children: Render>(title: &'a str, children: Children) {
rsx! {
}
}
pub fn some_page(user_name: &str) -> String {
html! {
<Page title={"Home"}>
{format!("Welcome, {}", user_name)}
</Page>
}
}
依赖关系
~1.5MB
~35K SLoC