属性
属性使子组件和父组件能够相互通信。每个组件都有一个关联的属性类型,用于描述从父组件向下传递的内容。理论上,这可以是任何实现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;
/// Importing the AttrValue from virtual_dom
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 {
/// The link must have a target.
href: AttrValue,
/// Also notice that we are using AttrValue instead of String
text: AttrValue,
/// Color of the link. Defaults to `Blue`.
#[prop_or_else(create_default_link_color)]
color: LinkColor,
/// The view function will not specify a size if this is None.
#[prop_or_default]
size: Option<u32>,
/// When the view function does not specify active, it defaults to 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 {
/// The link must have a target.
href: AttrValue,
/// Also notice that we're using AttrValue instead of String
text: AttrValue,
/// Color of the link. Defaults to `Blue`.
#[prop_or_else(create_default_link_color)]
color: LinkColor,
/// The view function will not specify a size if this is None.
#[prop_or_default]
size: Option<u32>,
/// When the view function doesn't specify active, it defaults to true.
#[prop_or(true)]
active: bool,
}
impl LinkProps {
/// Notice that this function receives href and text as String
/// We can use `AttrValue::from` to convert it to a `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,
}}
}
}