属性(Properties)
如“组 件(Components)”页面所述,Properties 用于父级到子组件的通信。
派生宏
不要尝试自己去实现 Properties
,而是通过使用 #[derive(Properties)]
来派生它。
必需属性
默认情况下,实现了 Properties
的结构体中的字段是必需的。当缺少了该字段并且在 html!
宏中创建了组件时,将返回编译错误。对于具有可选属性的字段,使用 #[prop_or_default]
来使用该类型的默认值。要指定一个值,请使用 #[prop_or_else(value)]
,其中 value 是该属性的默认值。例如,要将一个布尔值的默认值设置为 true
,请使用属性 #[prop_or_else(true)]
。可选属性通常使用 Option
,其默认值为 None
。
PartialEq
如果可以的话,在你的 props 上派生 PartialEq
通常是很有意义的。这使用了一个性能优化与最佳实践部分解释了的技巧,可以更轻松地避免重新渲染。
Properties 的内存/速度开销
记住组件的 view
函数签名:
fn view(&self) -> Html
你对组件的状态取了一个引用,并用来创建 Html
。但是 properties 是有所有权的值(owned values)。这意味着为了创造它们并且将它们传递给子组件,我们需要获取 view
函数里提供的引用的所有权。这是在将引用传递给组件时隐式克隆引用完成的,以获得构成其 props 的有所有权的值。
这意味着每个组件都有从 其父级传递来的状态的独特副本,而且,每当你重新渲染一个组件时,该重新渲染组件的所有子组件的 props 都将被克隆。
这意味着如果你将 大量 数据作为 props(大小为 10 KB 的字符串)向下传递,则可能需要考虑将子组件转换为在父级运行返回 Html
的函数,因为这样就不会被强制克隆你的数据。
另外,如果你不需要修改作为 props 传递的大数据,而只需要显示它,则可以将其包装在 Rc
中,以便仅克隆一个引用计数的指针,而不是数据本身。
示例
pub struct LinkColor {
Blue,
Red,
Green,
Black,
Purple,
}
impl Default for LinkColor {
fn default() -> Self {
// 除非另有说明,否则链接的颜色将为蓝色
LinkColor::Blue
}
}
#[derive(Properties, PartialEq)]
pub struct LinkProps {
/// 链接必须有一个目标地址
href: String,
/// 如果链接文本很大,这将使得复制字符串开销更小
/// 除非有性能问题,否则通常不建议这么做
text: Rc<String>,
/// 链接的颜色
#[prop_or_default]
color: LinkColor,
/// 如果为 None,则 view 函数将不指定大小
#[prop_or_default]
size: Option<u32>
/// 当 view 函数没有指定 active,其默认为 true
#[prop_or_else(true)]
active: bool,
}