條件渲染
If 區塊
要有條件地渲染一些標記,我們將其包裝在 if 區塊中:
- if
- if - else
- if let
- if let else
- let 綁定
use yew::prelude::*;
html! {
if true {
<p>{ "True case" }</p>
}
};
use yew::prelude::*;
let some_condition = true;
html! {
if some_condition {
<p>{ "True case" }</p>
} else {
<p>{ "False case" }</p>
}
};
use yew::prelude::*;
let some_text = Some("text");
html! {
if let Some(text) = some_text {
<p>{ text }</p>
}
};
use yew::prelude::*;
let some_text = Some("text");
html! {
if let Some(text) = some_text {
<p>{ text }</p>
} else {
<p>{ "False case" }</p>
}
};
大括號主體支援在 html 子節點前使用 let 綁定,以及多個子節點:
use yew::prelude::*;
html! {
if condition {
let label = format!("count: {count}");
<h2>{"Result"}</h2>
<span>{label}</span>
} else {
"nothing"
}
};
let 綁定必須出現在所有 html 子節點之前,不能與它們交錯。
Match 區塊
match 運算式可以直接在 html! 中使用,與 if/else 遵循相同的模式:
- match
- if 守衛
- let 綁定
use yew::prelude::*;
let value: Option<String> = Some("hello".into());
html! {
match value {
Some(text) => <p>{text}</p>,
None => <p>{"Nothing here"}</p>,
}
};
use yew::prelude::*;
let value: i32 = 42;
html! {
match value {
x if x > 10 => <p>{"Big"}</p>,
x if x > 0 => <p>{"Small"}</p>,
_ => <p>{"Non-positive"}</p>,
}
};
大括號 arm 主體支援 let 綁定和多個子節點:
use yew::prelude::*;
html! {
match data {
Some(item) => {
let label = format!("Item: {}", item.name);
let class = if item.important { "highlight" } else { "normal" };
<p class={class}>{label}</p>
}
None => <p>{"No data"}</p>,
}
};
單元素 arm 可以省略大括號。含多個子節點或 let 綁定的 arm 需要大括號。
match 支援所有標準 Rust 模式,包括 OR 模式(A | B)、解構和 if 守衛。窮舉性由 Rust 編譯器檢查。
if / match 主體內部的迴圈
if / else if / else / match 分支主體內部的 for、while、loop 與 html! 最外層位置的規則相同,但有一個例外:如果迴圈主體可以被 Rust 完整剖析(內部任何位置都沒有 html 元素),巨集會把這個迴圈視為 Rust 陳述式而不是 html 控制流。
最常見的觸發情形是迴圈主體裡只有一個裸 {expr} 區塊:
// 可以編譯。for 在最外層,被解析為 html-`for`。
html! {
for _ in 0..9 {
{my_foo}
}
}
// 無法編譯。for 在 `if` 內部,被解析為 Rust 陳述式;
// 之後 rustc 會回報迴圈主體傳回的型別不是 `()`。
html! {
if condition {
for _ in 0..9 {
{my_foo}
}
}
}
把子節點用 html 元素包起來即可保留 html-for 行為:
html! {
if condition {
for _ in 0..9 {
<span>{my_foo}</span>
}
}
}
完整的解決方法集合請參見清單。