传递子元素和属性
有时候,你会希望将一些重要的功能封装在你的状态中,而不是直接嵌套在另一个组件中。 在这些情况下,你需要将元素和属性传递到组件中,并让组件适当地放置它们。
本章我们主要会了解到:
- 传递子元素到组件。
- 传递属性到组件。
使用情况§
假设你正在构建一个网站,你需要对一个 <a>
标签进行封装:
rsx!(
a {
href: "https://google.com"
"Link to google"
}
)
如果你需要把 a
标签封装成一个组件:
#[derive(Props)]
struct ClickableProps<'a> {
href: &'a str,
title: &'a str
}
fn Clickable(cx: Scope<ClickableProps>) -> Element {
cx.render(rsx!(
a {
href: "{cx.props.href}"
"{cx.props.title}"
}
))
}
接下来你可以这么使用它:
rsx!(
Clickable {
href: "https://google.com"
title: "Link to Google"
}
)
传递子元素§
如果我们希望在我们的组件内可以嵌入其他子 元素/组件,那我们只需要定义一个类型为 Element 的道具:
#[derive(Props)]
struct ClickableProps<'a> {
href: &'a str,
body: Element<'a>
}
fn Clickable(cx: Scope<ClickableProps>) -> Element {
cx.render(rsx!(
a {
href: "{cx.props.href}",
&cx.props.body
}
))
}
使用它:
rsx!(
Clickable {
href: "https://google.com"
body: cx.render(rsx!(
img { src: "https://www.google.com/logos/doodles/..." }
))
}
)
Children
特殊项§
上面所介绍的在 Props
中嵌入一个子元素有时候使用起来并不方便,所以我们还内置了 Children
这种属性:
#[derive(Props)]
struct ClickableProps<'a> {
href: &'a str,
children: Element<'a>
}
fn clickable(cx: Scope<ClickableProps>) -> Element {
cx.render(rsx!(
a {
href: "{cx.props.href}",
&cx.props.children
}
))
}
使用它则会方便很多:
rsx!(
Clickable {
href: "https://google.com"
img { src: "https://www.google.com/logos/doodles/...." }
}
)
它更像我们原生的 HTML 标签组件那种嵌入子元素了。
传递属性§
你也可以将属性信息在 Props
中传递:
rsx!(
Clickable {
"class": "blue-button",
"style": "background: red;"
}
)
传递属性,你需要添加 attributes
字段:
#[derive(Props)]
struct ClickableProps<'a> {
attributes: Attributes<'a>
}
fn clickable(cx: Scope<ClickableProps>) -> Element {
cx.render(rsx!(
a {
..cx.props.attributes,
"Any link, anywhere"
}
))
}
传递处理器§
Dioxus 支持对 on
事件的传递,你可以为你的组件绑定各类事件:
#[derive(Props)]
struct ClickableProps<'a> {
onclick: EventHandler<'a, MouseEvent>
}
fn clickable(cx: Scope<ClickableProps>) -> Element {
cx.render(rsx!(
a {
onclick: move |evt| cx.props.onclick.call(evt)
}
))
}
我们可以在使用组件的时候这样绑定它:
rsx!(
Clickable {
onclick: move |_| log::info!("Clicked"),
}
)
这样子当 a
标签被点击时,就会触发 log::info!
的功能。