mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
* 0.20 Changelog * Improve changelog generator * Add blog post * Add blog post * Apply suggestions from code review Co-authored-by: WorldSEnder <WorldSEnder@users.noreply.github.com> Co-authored-by: Julius Lungys <32368314+voidpumpkin@users.noreply.github.com> * update Changelog * update Cargo.toml * changelog gen compiles * website version 0.20 * add migration guides * prettier * i18n Co-authored-by: WorldSEnder <WorldSEnder@users.noreply.github.com> Co-authored-by: Julius Lungys <32368314+voidpumpkin@users.noreply.github.com>
173 lines
4.1 KiB
Plaintext
173 lines
4.1 KiB
Plaintext
---
|
|
title: 'Components'
|
|
description: 'Create complex layouts with component hierarchies'
|
|
---
|
|
|
|
## Basic
|
|
|
|
Components can be used in the `html!` macro:
|
|
|
|
```rust
|
|
use yew::prelude::*;
|
|
|
|
#[function_component]
|
|
fn MyComponent() -> Html {
|
|
html! {
|
|
{ "This component has no properties!" }
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, PartialEq, Properties)]
|
|
struct Props {
|
|
user_first_name: String,
|
|
user_last_name: String,
|
|
}
|
|
|
|
#[function_component]
|
|
fn MyComponentWithProps(props: &Props) -> Html {
|
|
let Props { user_first_name, user_last_name } = props;
|
|
html! {
|
|
<>{"user_first_name: "}{user_first_name}{" and user_last_name: "}{user_last_name}</>
|
|
}
|
|
}
|
|
|
|
let props = Props {
|
|
user_first_name: "Bob".to_owned(),
|
|
user_last_name: "Smith".to_owned(),
|
|
};
|
|
|
|
html!{
|
|
<>
|
|
// No properties
|
|
<MyComponent />
|
|
|
|
// With Properties
|
|
<MyComponentWithProps user_first_name="Sam" user_last_name="Idle" />
|
|
|
|
// With the whole set of props provided at once
|
|
<MyComponentWithProps ..props.clone() />
|
|
|
|
// With Properties from a variable and specific values overridden
|
|
<MyComponentWithProps user_last_name="Elm" ..props />
|
|
</>
|
|
};
|
|
```
|
|
|
|
## Nested
|
|
|
|
Components can be passed children if they have a `children` field in their `Properties`.
|
|
|
|
```rust title="parent.rs"
|
|
use yew::prelude::*;
|
|
|
|
#[derive(PartialEq, Properties)]
|
|
struct Props {
|
|
id: String,
|
|
children: Children,
|
|
}
|
|
|
|
#[function_component]
|
|
fn Container(props: &Props) -> Html {
|
|
html! {
|
|
<div id={props.id.clone()}>
|
|
{ props.children.clone() }
|
|
</div>
|
|
}
|
|
}
|
|
|
|
html! {
|
|
<Container id="container">
|
|
<h4>{ "Hi" }</h4>
|
|
<div>{ "Hello" }</div>
|
|
</Container>
|
|
};
|
|
```
|
|
|
|
The `html!` macro allows you to pass a base expression with the `..props` syntax instead of specifying each property individually,
|
|
similar to Rust's [Functional Update Syntax](https://doc.rust-lang.org/stable/reference/expressions/struct-expr.html#functional-update-syntax).
|
|
This base expression must occur after any individual props are passed.
|
|
When passing a base props expression with a `children` field, the children passed in the `html!` macro overwrite the ones already present in the props.
|
|
|
|
```rust
|
|
use yew::prelude::*;
|
|
|
|
#[derive(PartialEq, Properties)]
|
|
struct Props {
|
|
id: String,
|
|
children: Children,
|
|
}
|
|
|
|
#[function_component]
|
|
fn Container(props: &Props) -> Html {
|
|
html! {
|
|
<div id={props.id.clone()}>
|
|
{ props.children.clone() }
|
|
</div>
|
|
}
|
|
}
|
|
|
|
let props = yew::props!(Props {
|
|
id: "container-2",
|
|
children: Children::default(),
|
|
});
|
|
|
|
html! {
|
|
<Container ..props>
|
|
// props.children will be overwritten with this
|
|
<span>{ "I am a child, as you can see" }</span>
|
|
</Container>
|
|
};
|
|
```
|
|
|
|
## Nested Children with Props
|
|
|
|
Nested component properties can be accessed and mutated if the containing component types its children. In the following example, the `List` component can wrap `ListItem` components. For a real world example of this pattern, check out the `yew-router` source code. For a more advanced example, check out the `nested-list` example in the main yew repository.
|
|
|
|
```rust
|
|
use std::rc::Rc;
|
|
use yew::prelude::*;
|
|
|
|
#[derive(Clone, PartialEq, Properties)]
|
|
pub struct ListItemProps {
|
|
value: String,
|
|
}
|
|
|
|
#[function_component]
|
|
fn ListItem(props: &ListItemProps) -> Html {
|
|
let ListItemProps { value } = props.clone();
|
|
html! {
|
|
<span>
|
|
{value}
|
|
</span>
|
|
}
|
|
}
|
|
|
|
#[derive(PartialEq, Properties)]
|
|
pub struct Props {
|
|
pub children: ChildrenWithProps<ListItem>,
|
|
}
|
|
|
|
#[function_component]
|
|
fn List(props: &Props) -> Html {
|
|
let modified_children = props.children.iter().map(|mut item| {
|
|
let mut props = Rc::make_mut(&mut item.props);
|
|
props.value = format!("item-{}", props.value);
|
|
item
|
|
});
|
|
html! { for modified_children }
|
|
}
|
|
|
|
html! {
|
|
<List>
|
|
<ListItem value="a" />
|
|
<ListItem value="b" />
|
|
<ListItem value="c" />
|
|
</List>
|
|
};
|
|
```
|
|
|
|
## Relevant examples
|
|
|
|
- [Function Todo MVC](https://github.com/yewstack/yew/tree/master/examples/function_todomvc)
|
|
- [Function Router](https://github.com/yewstack/yew/tree/master/examples/function_router)
|