Skip to main content
Version: Next

属性 (Props)

属性 (Properties) 使子组件和父组件之间能够进行通信。每个组件都有一个关联的属性类型,用于描述从父组件传递下来的内容。理论上,这可以是任何实现了 Properties 特性的类型,但实际上,它应该是一个结构体,其中每个字段代表一个属性。

派生宏

无需自己实现 Properties 特性,我们可以用 #[derive(Properties)] 来自动生成实现。派生 Properties 的类型也必须实现 PartialEq

字段属性

在派生 Properties 时,默认情况下所有字段都是必需的。以下属性允许您为属性提供初始值,除非它们被设置为另一个值。

提示

属性不会在 Rustdoc 生成的文档中显示。您的属性的文档字符串应该说明一个属性是否是可选的,以及它是否有一个特殊的默认值。

#[prop_or_default]

使用字段类型的默认值使用 Default 特性来初始化属性值。

#[prop_or(value)]

使用 value 来初始化属性值。value 可以是返回字段类型的任何表达式。例如,要将布尔属性默认为 true,请使用属性 #[prop_or(true)]

#[prop_or_else(function)]

调用 function 来初始化属性值。function 应该具有签名 FnMut() -> T,其中 T 是字段类型。

PartialEq

Properties 需要实现 PartialEq。这样,Yew 才能比较它们,以便在它们发生变化时调用 changed 方法。

使用 Properties 的性能开销

内部属性是基于引用计数的指针存储的。这意味着只有一个指针被传递到组件树中的属性,以避免克隆整个属性所带来的昂贵性能开销。

提示

使用 AttrValue,这是我们提供的自定义属性值类型,这样就可以不用 String 或其他类似的需要克隆的类型。

示例

use yew::Properties;
/// 从 virtual_dom 中导入 AttrValue
use yew::virtual_dom::AttrValue;

#[derive(Clone, PartialEq)]
pub enum LinkColor {
Blue,
Red,
Green,
Black,
Purple,
}

fn create_default_link_color() -> LinkColor {
LinkColor::Blue
}

#[derive(Properties, PartialEq)]
pub struct LinkProps {
/// 链接必须有一个目标
href: AttrValue,
/// 还要注意我们使用的是 AttrValue 而不是 String
text: AttrValue,
/// 链接的颜色,默认为 `Blue`
#[prop_or_else(create_default_link_color)]
color: LinkColor,
/// 如果值为 None,则视图函数不会指定大小
#[prop_or_default]
size: Option<u32>,
/// 当视图函数没有指定活动时,默认为 true
#[prop_or(true)]
active: bool,
}

Props 宏

yew::props! 宏允许您以与 html! 宏相同的方式构建属性。

该宏使用与结构体表达式相同的语法,只是您不能使用属性或基本表达式 (Foo { ..base })。类型路径可以直接指向属性 (path::to::Props),也可以指向组件的关联属性 (MyComp::Properties)。

use yew::{props, Properties, virtual_dom::AttrValue};

#[derive(Clone, PartialEq)]
pub enum LinkColor {
Blue,
Red,
Green,
Black,
Purple,
}

fn create_default_link_color() -> LinkColor {
LinkColor::Blue
}

#[derive(Properties, PartialEq)]
pub struct LinkProps {
/// 链接必须有一个目标
href: AttrValue,
/// 还要注意我们使用的是 AttrValue 而不是 String
text: AttrValue,
/// 链接的颜色,默认为 `Blue`
#[prop_or_else(create_default_link_color)]
color: LinkColor,
/// 如果值为 None,则视图函数不会指定大小
#[prop_or_default]
size: Option<u32>,
/// 当视图函数没有指定活动时,默认为 true
#[prop_or(true)]
active: bool,
}

impl LinkProps {
/// 注意此函数接收 href 和 text 作为 String
/// 我们可以使用 `AttrValue::from` 将其转换为 `AttrValue`
pub fn new_link_with_size(href: String, text: String, size: u32) -> Self {
props! {LinkProps {
href: AttrValue::from(href),
text: AttrValue::from(text),
size,
}}
}
}