8个不稳定版本 (3个重大更改)
0.4.0 | 2022年9月17日 |
---|---|
0.3.3 | 2022年9月17日 |
0.2.1 | 2022年9月17日 |
0.1.0 | 2022年9月17日 |
#188 in 模板引擎
每月下载量161次
22KB
298 行
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>
}
}
依赖项
~9-20MB
~303K SLoC