dependabot[bot] 7ea787285e
Bump the website-deps group across 1 directory with 15 updates (#3798)
* Bump the website-deps group across 1 directory with 15 updates

Bumps the website-deps group with 14 updates in the /website directory:

| Package | From | To |
| --- | --- | --- |
| [@docusaurus/core](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus) | `3.5.2` | `3.7.0` |
| [@docusaurus/plugin-client-redirects](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-plugin-client-redirects) | `3.5.2` | `3.7.0` |
| [@docusaurus/preset-classic](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-preset-classic) | `3.5.2` | `3.7.0` |
| [@mdx-js/react](https://github.com/mdx-js/mdx/tree/HEAD/packages/react) | `3.0.1` | `3.1.0` |
| [docusaurus-plugin-sass](https://github.com/rlamana/docusaurus-plugin-sass) | `0.2.5` | `0.2.6` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `18.3.1` | `19.0.0` |
| [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) | `18.3.10` | `19.0.8` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `18.3.1` | `19.0.0` |
| [sass](https://github.com/sass/dart-sass) | `1.79.4` | `1.83.4` |
| [@docusaurus/tsconfig](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-tsconfig) | `3.5.2` | `3.7.0` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.8.0` | `8.22.0` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.8.0` | `8.22.0` |
| [prettier](https://github.com/prettier/prettier) | `3.3.3` | `3.4.2` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.6.2` | `5.7.3` |



Updates `@docusaurus/core` from 3.5.2 to 3.7.0
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.7.0/packages/docusaurus)

Updates `@docusaurus/plugin-client-redirects` from 3.5.2 to 3.7.0
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.7.0/packages/docusaurus-plugin-client-redirects)

Updates `@docusaurus/preset-classic` from 3.5.2 to 3.7.0
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.7.0/packages/docusaurus-preset-classic)

Updates `@mdx-js/react` from 3.0.1 to 3.1.0
- [Release notes](https://github.com/mdx-js/mdx/releases)
- [Changelog](https://github.com/mdx-js/mdx/blob/main/changelog.md)
- [Commits](https://github.com/mdx-js/mdx/commits/3.1.0/packages/react)

Updates `docusaurus-plugin-sass` from 0.2.5 to 0.2.6
- [Release notes](https://github.com/rlamana/docusaurus-plugin-sass/releases)
- [Commits](https://github.com/rlamana/docusaurus-plugin-sass/compare/v0.2.5...v0.2.6)

Updates `react` from 18.3.1 to 19.0.0
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.0.0/packages/react)

Updates `@types/react` from 18.3.10 to 19.0.8
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 18.3.1 to 19.0.0
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.0.0/packages/react-dom)

Updates `sass` from 1.79.4 to 1.83.4
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.79.4...1.83.4)

Updates `@docusaurus/module-type-aliases` from 3.5.2 to 3.7.0
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.7.0/packages/docusaurus-module-type-aliases)

Updates `@docusaurus/tsconfig` from 3.5.2 to 3.7.0
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.7.0/packages/docusaurus-tsconfig)

Updates `@types/react` from 18.3.10 to 19.0.8
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@typescript-eslint/eslint-plugin` from 8.8.0 to 8.22.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.22.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.8.0 to 8.22.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.22.0/packages/parser)

Updates `prettier` from 3.3.3 to 3.4.2
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.3.3...3.4.2)

Updates `typescript` from 5.6.2 to 5.7.3
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.6.2...v5.7.3)

---
updated-dependencies:
- dependency-name: "@docusaurus/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: website-deps
- dependency-name: "@docusaurus/plugin-client-redirects"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: website-deps
- dependency-name: "@docusaurus/preset-classic"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: website-deps
- dependency-name: "@mdx-js/react"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: website-deps
- dependency-name: docusaurus-plugin-sass
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: website-deps
- dependency-name: react
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: website-deps
- dependency-name: "@types/react"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: website-deps
- dependency-name: react-dom
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: website-deps
- dependency-name: sass
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: website-deps
- dependency-name: "@docusaurus/module-type-aliases"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: website-deps
- dependency-name: "@docusaurus/tsconfig"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: website-deps
- dependency-name: "@types/react"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: website-deps
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: website-deps
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: website-deps
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: website-deps
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: website-deps
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: fix formatting

* chore: bump prettier (can't reproduce element.mdx warning locally?)

* workflow: show formatting diff for locally unproduceable errors

* chore: format elements.mdx

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Matt Yan <syan4@ualberta.ca>
Co-authored-by: Siyuan Yan <44753941+Madoshakalaka@users.noreply.github.com>
2025-02-21 07:33:40 +09:00

462 lines
16 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: '路由 (Router)'
description: 'Yew 的官方路由库'
---
单页应用程序 (SPA) 中的路由器处理根据 URL 显示不同的页面。与点击链接时请求不同的远程资源的默认行为不同,路由器会在本地设置 URL 以指向应用程序中的有效路由。然后,路由器检测到此更改并决定要渲染的内容。
Yew 在 `yew-router` crate 中提供了路由器支持。要开始使用它,请将依赖项添加到您的 `Cargo.toml` 文件中。
<!-- Reminder: fix this when we release a new version of yew -->
```toml
yew-router = { git = "https://github.com/yewstack/yew.git" }
```
所需的工具均在 `yew_router::prelude` 模块中提供,
## 用法
最开始,你需要定义一个 `Route`。
路由由一个 `enum` 定义,它派生自 `Routable`。这个枚举必须实现 `Clone + PartialEq`。
```rust
use yew_router::prelude::*;
#[derive(Clone, Routable, PartialEq)]
enum Route {
#[at("/")]
Home,
#[at("/secure")]
Secure,
#[not_found]
#[at("/404")]
NotFound,
}
```
`Route` 与 `<Switch />` 组件配对,后者会找到与浏览器当前 URL 匹配的路径变体,并将其传递给 `render` 回调。然后回调决定要渲染的内容。如果没有路径匹配,路由器会导航到带有 `not_found` 属性的路径。如果没有指定路由,则不会渲染任何内容,并且会在控制台中记录一条消息,说明没有匹配的路由。
yew-router 的大多数组件,特别是 `<Link />` 和 `<Switch />`,必须是某个 Router 组件(例如 `<BrowserRouter />`)的(深层)子元素。通常在应用程序中只需要一个 Router通常由最顶层的 `<App />` 组件立即渲染。Router 注册了一个上下文,这是 Links 和 Switches 功能所需的。下面提供了一个示例。
:::caution
在浏览器环境中使用 `yew-router` 时,强烈推荐使用 `<BrowserRouter />`。您可以在 [API 参考](https://docs.rs/yew-router/) 中找到其他路由器类型。
:::
```rust
use yew_router::prelude::*;
use yew::prelude::*;
#[derive(Clone, Routable, PartialEq)]
enum Route {
#[at("/")]
Home,
#[at("/secure")]
Secure,
#[not_found]
#[at("/404")]
NotFound,
}
#[function_component(Secure)]
fn secure() -> Html {
let navigator = use_navigator().unwrap();
let onclick = Callback::from(move |_| navigator.push(&Route::Home));
html! {
<div>
<h1>{ "Secure" }</h1>
<button {onclick}>{ "Go Home" }</button>
</div>
}
}
fn switch(routes: Route) -> Html {
match routes {
Route::Home => html! { <h1>{ "Home" }</h1> },
Route::Secure => html! {
<Secure />
},
Route::NotFound => html! { <h1>{ "404" }</h1> },
}
}
#[function_component(Main)]
fn app() -> Html {
html! {
<BrowserRouter>
<Switch<Route> render={switch} /> // <- must be child of <BrowserRouter>
</BrowserRouter>
}
}
```
### 路径段
路由还可以使用动态和命名通配符段从路由中提取信息。然后,您可以在 `<Switch />` 内访问帖子的 id并通过属性将其转发到相应的组件。
```rust
use yew::prelude::*;
use yew_router::prelude::*;
#[derive(Clone, Routable, PartialEq)]
enum Route {
#[at("/")]
Home,
#[at("/post/:id")]
Post { id: String },
#[at("/*path")]
Misc { path: String },
}
fn switch(route: Route) -> Html {
match route {
Route::Home => html! { <h1>{ "Home" }</h1> },
Route::Post { id } => html! {<p>{format!("You are looking at Post {}", id)}</p>},
Route::Misc { path } => html! {<p>{format!("Matched some other path: {}", path)}</p>},
}
}
```
:::note
您也可以使用普通的 `Post` 变体,而不是 `Post {id: String}`。例如,当 `Post` 与另一个路由器一起渲染时,该字段可能是多余的,因为另一个路由器可以匹配并处理路径。有关详细信息,请参阅下面的[嵌套路由器](#nested-router)部分。
:::
请注意,字段必须实现 `Clone + PartialEq` 作为 `Route` 枚举的一部分。它们还必须实现 `std::fmt::Display` 和 `std::str::FromStr` 以进行序列化和反序列化。整数、浮点数和字符串等原始类型已经满足这些要求。
当路径的形式匹配,但反序列化失败(根据 `FromStr`)时。路由器将认为路由不匹配,并尝试渲染未找到的路由(或者如果未指定未找到的路由,则渲染空白页面)。
参考以下示例:
```rust ,ignore
#[derive(Clone, Routable, PartialEq)]
enum Route {
#[at("/news/:id")]
News { id: u8 },
#[not_found]
#[at("/404")]
NotFound,
}
// 切换函数会渲染 News 和 id。这里省略了。
```
当段超过 255 时,`u8::from_str()` 将失败并返回 `ParseIntError`,路由器将认为路由不匹配。
![router deserialization failure behavior](/img/router-deserialization-failure-behavior.gif)
有关路由语法和如何绑定参数的更多信息,请查看 [route-recognizer](https://docs.rs/route-recognizer/0.3.1/route_recognizer/#routing-params)。
### 位置 (Location)
路由器通过上下文提供了一个通用的 `Location` 结构,可以用于访问路由信息。它们可以通过钩子或 `ctx.link()` 上的便捷函数来检索。
### 导航
`yew_router` 提供了一些工具来处理导航。
#### 链接
`<Link />` 渲染为 `<a>` 元素,`onclick` 事件处理程序将调用 [preventDefault](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault),并将目标页面推送到历史记录中并渲染所需的页面,这正是单页应用程序所期望的行为。普通锚元素的默认 `onclick` 会重新加载页面。
`<Link />` 组件还会将其子元素传递给 `<a>` 元素。可以将其视为应用内路由的 `<a/>` 替代品。不同之处在于你需要提供 `to` 属性而不是 `href`。示例用法如下:
```rust ,ignore
<Link<Route> to={Route::Home}>{ "click here to go home" }</Link<Route>>
```
结构体变量也可以正常工作:
```rust ,ignore
<Link<Route> to={Route::Post { id: "new-yew-release".to_string() }}>{ "Yew!" }</Link<Route>>
```
#### 导航接口
导航器 API 为函数组件和结构组件提供。它们使回调能够更改路由。可以在任一情况下获取 `Navigator` 实例以操作路由。
##### 函数式组件
对于函数组件,当底层导航器提供程序更改时,`use_navigator` 钩子会重新渲染组件。
以下是实现一个按钮的示例,该按钮在点击时导航到 `Home` 路由。
```rust ,ignore
#[function_component(MyComponent)]
pub fn my_component() -> Html {
let navigator = use_navigator().unwrap();
let onclick = Callback::from(move |_| navigator.push(&Route::Home));
html! {
<>
<button {onclick}>{"Click to go home"}</button>
</>
}
}
```
:::caution
这里的示例使用了 `Callback::from`。如果目标路由可以与组件所在的路由相同,或者只是为了安全起见,请使用普通的回调。例如,考虑在每个页面上都有一个徽标按钮,点击该按钮会返回主页。在主页上点击该按钮两次会导致代码崩溃,因为第二次点击会推送一个相同的 Home 路由,并且 `use_navigator` 钩子不会触发重新渲染。
:::
如果您想替换当前的位置而不是将新位置推到堆栈上,请使用 `navigator.replace()` 而不是 `navigator.push()`。
您可能会注意到 `navigator` 必须移动到回调中,因此不能再次用于其他回调。幸运的是,`navigator` 实现了 `Clone`,例如,以下是如何为不同的路由设置多个按钮:
```rust ,ignore
use yew::prelude::*;
use yew_router::prelude::*;
#[function_component(NavItems)]
pub fn nav_items() -> Html {
let navigator = use_navigator().unwrap();
let go_home_button = {
let navigator = navigator.clone();
let onclick = Callback::from(move |_| navigator.push(&Route::Home));
html! {
<button {onclick}>{"click to go home"}</button>
}
};
let go_to_first_post_button = {
let navigator = navigator.clone();
let onclick = Callback::from(move |_| navigator.push(&Route::Post { id: "first-post".to_string() }));
html! {
<button {onclick}>{"click to go the first post"}</button>
}
};
let go_to_secure_button = {
let onclick = Callback::from(move |_| navigator.push(&Route::Secure));
html! {
<button {onclick}>{"click to go to secure"}</button>
}
};
html! {
<>
{go_home_button}
{go_to_first_post_button}
{go_to_secure_button}
</>
}
}
```
##### 结构体组件
对于结构体组件,可以通过 `ctx.link().navigator()` API 获取 `Navigator` 实例。其余部分与函数组件的情况相同。以下是一个渲染单个按钮的视图函数示例。
```rust ,ignore
fn view(&self, ctx: &Context<Self>) -> Html {
let navigator = ctx.link().navigator().unwrap();
let onclick = Callback::from(move |_| navigator.push(&MainRoute::Home));
html!{
<button {onclick}>{"Go Home"}</button>
}
}
```
#### 重定向
`yew-router` 还在 prelude 中提供了一个 `<Redirect />` 组件。它可以用于实现与导航器 API 类似的效果。该组件接受一个 `to` 属性作为目标路由。当渲染 `<Redirect/>` 时,用户将被重定向到属性中指定的路由。以下是一个示例:
```rust ,ignore
#[function_component(SomePage)]
fn some_page() -> Html {
// 建立对 `use_user` 的钩子
let user = match use_user() {
Some(user) => user,
// 当用户为 `None` 时重定向到登录页面
None => return html! {
<Redirect<Route> to={Route::Login}/>
},
};
// ... 实际页面内容
}
```
:::tip 如何选择 `Redirect` 或 `Navigator`
Navigator API 是在回调中操作路由的唯一方法。
而 `<Redirect />` 可以作为组件中的返回值使用。您可能还希望在其他非组件上下文中使用 `<Redirect />`,例如在[嵌套路由器](#nested-router)的 switch 函数中。
:::
### 监听变化
#### 函数式组件
您可以使用 `use_location` 和 `use_route` 钩子。当提供的值发生变化时,您的组件将重新渲染。
#### 结构体组件
为了响应路由变化,您可以将回调闭包传递给 `ctx.link()` 的 `add_location_listener()` 方法。
:::note
一旦位置监听器被删除,它将被取消注册。请确保将句柄存储在组件状态中。
:::
```rust ,ignore
fn create(ctx: &Context<Self>) -> Self {
let listener = ctx.link()
.add_location_listener(ctx.link().callback(
// 处理事件
))
.unwrap();
MyComponent {
_listener: listener
}
}
```
`ctx.link().location()` 和 `ctx.link().route::<R>()` 也可以用于一次性检索位置和路由。
### 查询参数
#### 在导航时指定查询参数
为了在导航到新路由时指定查询参数,可以使用 `navigator.push_with_query` 或 `navigator.replace_with_query` 函数。它使用 `serde` 将参数序列化为 URL 的查询字符串,因此任何实现了 `Serialize` 的类型都可以传递。最简单的形式是包含字符串对的 `HashMap`。
#### 获取当前路由的查询参数
`location.query` 用于获取查询参数。它使用 `serde` 从 URL 的查询字符串中反序列化参数。
## 嵌套路由器
当应用程序变得更大时,嵌套路由器可能会很有用。考虑以下路由器结构:
<!--
The graph is produced with the following code, with graphviz.
To reproduce. Save the code in a file, say `input.dot`,
And run `$ dot -Tsvg input.dot -o nested-router.svg`
digraph {
bgcolor=transparent
node [shape=box style="filled, rounded" fillcolor=white]
Home; News; Contact; "Not Found"; Profile; Friends; Theme; SettingsNotFound [label="Not Found"];
node [fillcolor=lightblue style="filled, rounded"]
"Main Router"; "Settings Router";
"Main Router" -> {Home News Contact "Not Found" "Settings Router"} [arrowhead=none]
"Settings Router" -> {SettingsNotFound Profile Friends Theme } [arrowhead=none]
SettingsNotFound -> "Not Found" [constraint=false]
}
-->
<!--
Also the dark-themed version:
digraph {
bgcolor=transparent
node [shape=box style="filled, rounded" fillcolor=grey color=white fontcolor=white]
Home; News; Contact; "Not Found"; Profile; Friends; Theme; SettingsNotFound [label="Not Found"];
node [fillcolor=lightblue style="filled, rounded" color=white fontcolor=black]
"Main Router"; "Settings Router";
"Main Router" -> {Home News Contact "Not Found" "Settings Router"} [arrowhead=none color=white]
"Settings Router" -> {SettingsNotFound Profile Friends Theme } [arrowhead=none color=white]
SettingsNotFound -> "Not Found" [constraint=false color=white]
}
-->
import useBaseUrl from '@docusaurus/useBaseUrl'
import ThemedImage from '@theme/ThemedImage'
<ThemedImage
alt="nested router structure"
sources={{
light: useBaseUrl('/img/nested-router-light.svg'),
dark: useBaseUrl('/img/nested-router-dark.svg'),
}}
/>
嵌套的 `SettingsRouter` 处理所有以 `/settings` 开头的 URL。此外它会将未匹配的 URL 重定向到主 `NotFound` 路由。因此,`/settings/gibberish` 将重定向到 `/404`。
:::caution
请注意,该接口仍在开发中,这样写的方式尚未最终确定
:::
可以使用以下代码实现:
```rust
use yew::prelude::*;
use yew_router::prelude::*;
use gloo::utils::window;
use wasm_bindgen::UnwrapThrowExt;
#[derive(Clone, Routable, PartialEq)]
enum MainRoute {
#[at("/")]
Home,
#[at("/news")]
News,
#[at("/contact")]
Contact,
#[at("/settings")]
SettingsRoot,
#[at("/settings/*")]
Settings,
#[not_found]
#[at("/404")]
NotFound,
}
#[derive(Clone, Routable, PartialEq)]
enum SettingsRoute {
#[at("/settings")]
Profile,
#[at("/settings/friends")]
Friends,
#[at("/settings/theme")]
Theme,
#[not_found]
#[at("/settings/404")]
NotFound,
}
fn switch_main(route: MainRoute) -> Html {
match route {
MainRoute::Home => html! {<h1>{"Home"}</h1>},
MainRoute::News => html! {<h1>{"News"}</h1>},
MainRoute::Contact => html! {<h1>{"Contact"}</h1>},
MainRoute::SettingsRoot | MainRoute::Settings => html! { <Switch<SettingsRoute> render={switch_settings} /> },
MainRoute::NotFound => html! {<h1>{"Not Found"}</h1>},
}
}
fn switch_settings(route: SettingsRoute) -> Html {
match route {
SettingsRoute::Profile => html! {<h1>{"Profile"}</h1>},
SettingsRoute::Friends => html! {<h1>{"Friends"}</h1>},
SettingsRoute::Theme => html! {<h1>{"Theme"}</h1>},
SettingsRoute::NotFound => html! {<Redirect<MainRoute> to={MainRoute::NotFound}/>}
}
}
#[function_component(App)]
pub fn app() -> Html {
html! {
<BrowserRouter>
<Switch<MainRoute> render={switch_main} />
</BrowserRouter>
}
}
```
### 基底路径 (Basename)
可以使用 `yew-router` 定义基底路径 (Basename)。
基底路径是所有路由的公共前缀。导航器 API 和 `<Switch />` 组件都支持基底路径设置。所有推送的路由都会加上基底路径前缀,所有的 switch 都会在尝试将路径解析为 `Routable` 之前去掉基底路径。
如果没有为 Router 组件提供基底路径属性,它将使用 HTML 文件中 `<base />` 元素的 href 属性,并在 HTML 文件中没有 `<base />` 元素时回退到 `/`。
## 相关示例
- [路由](https://github.com/yewstack/yew/tree/master/examples/router)
## 接口参考
- [yew-router](https://docs.rs/yew-router/)