Matt 90b4e55ebc
Docusaurus Overhaul (#2275)
* change suffixes from md to mdx
fix broken links for English locale
tree shake and update docusaurus
add docusaurus ideal image plugin
use svg and themed image
delete unused static asset

* move localized landing page

* change GitLocalize project page

* nit pick

* remove ignore to have the block checked
2021-12-20 12:10:45 +02:00

138 lines
4.0 KiB
Plaintext

---
title: "Properties"
description: "Parent to child communication"
---
Properties enable child and parent components to communicate with each other.
Every component has an associated properties type which describes what is passed down from the parent.
In theory this can be any type that implements the `Properties` trait, but in practice there's no
reason for it to be anything but a struct where each field represents a property.
## Derive macro
Instead of implementing the `Properties` trait yourself, you should use `#[derive(Properties)]` to
automatically generate the implementation instead.
Types for which you derive `Properties` must also implement `PartialEq`.
### Field attributes
When deriving `Properties`, all fields are required by default.
The following attributes allow you to give your props initial values which will be used unless they're set to another value.
:::tip
Attributes aren't visible in Rustdoc generated documentation.
The docstrings of your properties should mention whether a prop is optional and if it has a special default value.
:::
#### `#[prop_or_default]`
Initialize the prop value with the default value of the field's type using the `Default` trait.
#### `#[prop_or(value)]`
Use `value` to initialize the prop value. `value` can be any expression that returns the field's type.
For example, to default a boolean prop to `true`, use the attribute `#[prop_or(true)]`.
#### `#[prop_or_else(function)]`
Call `function` to initialize the prop value. `function` should have the signature `FnMut() -> T` where `T` is the field type.
## `PartialEq`
`Properties` require `PartialEq` to be implemented. This is so that they can be compared by Yew to call the `changed` method
only when they change.
## Memory/speed overhead of using Properties
Internally properties are reference counted. This means that only a pointer is passed down the component tree for props.
It saves us from the cost of having to clone the entire props, which might be expensive.
## Example
```rust
use std::rc::Rc;
use yew::Properties;
#[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: String,
text: String,
/// 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,
}
```
## Props macro
The `yew::props!` macro allows you to build properties the same way the `html!` macro does it.
The macro uses the same syntax as a struct expression except that you can't use attributes or a base expression (`Foo { ..base }`).
The type path can either point to the props directly (`path::to::Props`) or the associated properties of a component (`MyComp::Properties`).
```rust
use std::rc::Rc;
use yew::{props, Properties};
#[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: String,
text: Rc<String>,
/// 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 {
pub fn new_link_with_size(href: String, text: String, size: u32) -> Self {
// highlight-start
props! {LinkProps {
href,
text: Rc::from(text),
size,
}}
// highlight-end
}
}
```