finish router refrence

This commit is contained in:
Evan Almloff committed 2023-06-01 17:31:13 -05:00
1 parent 07446386e6
commit b5a2f0d6cb
61 files changed
+676 -1908

No files matched your search

+9 -187
View File
@@ -19,199 +19,21 @@ We might want to map this structure to these paths and components:
/settings/privacy -> Settings { PrivacySettings }
```
Nested routes allow us to do this.
Nested routes allow us to do this without repeating /settings in every route.
## Route Depth
## Nesting
With nesting routes, the router manages content on multiple levels. In our
example, when the path is `/settings`, there are two levels of content:
To nest routes, we use the `#[nest("path")]` and `#[end_nest]` attributes.
0. The `Settings` component
1. The `GeneralSettings` component
The path in nest must not:
Dioxus Router uses the [`Outlet`] component to actually render content, but each
[`Outlet`] can only render content from one level. This means that for the
content of nested routes to actually be rendered, we also need nested
[`Outlet`]s.
1. Contain a [Catch All Segment](index.md#catch-all-segments)
2. Contain a [Query Segment](index.md#query-segments)
## Defining the content components
If you define a dynamic segment in a nest, it will be available to all child routes and layouts.
We start by creating the components we want the router to render.
Take a look at the `Settings` component. When it gets rendered by an [`Outlet`],
it will render a second [`Outlet`]. Thus the second [`Outlet`] is nested within
the first one, and will in turn render our nested content.
To finish a nest, we use the `#[end_nest]` attribute or the end of the enum.
```rust, no_run
# // Hidden lines (like this one) make the documentation tests work.
# extern crate dioxus;
# use dioxus::prelude::*;
# extern crate dioxus_router;
# use dioxus_router::prelude::*;
#
fn Settings(cx: Scope) -> Element {
render! {
h1 { "Settings" }
Outlet { }
}
}
fn GeneralSettings(cx: Scope) -> Element {
render! {
h2 { "General Settings" }
}
}
fn PWSettings(cx: Scope) -> Element {
render! {
h2 { "Password Settings" }
}
}
fn PrivacySettings(cx: Scope) -> Element {
render! {
h2 { "Privacy Settings" }
}
}
{{#include ../../../examples/nest.rs:route}}
```
## Defining the root [`Segment`]
Now we create the [`Segment`] that we will pass to the router.
Note that we wrap `comp(Settings)` within a [`Route`]. For this exact code that
is unnecessary, as this would be done automatically. However, in the next step
we'll use a method of [`Route`], so we might as well add this now.
```rust, no_run
# // Hidden lines (like this one) make the documentation tests work.
# extern crate dioxus;
# use dioxus::prelude::*;
# extern crate dioxus_router;
# use dioxus_router::prelude::*;
# fn Settings(cx: Scope) -> Element { unimplemented!() }
#
fn App(cx: Scope) -> Element {
use_router(
cx,
&|| RouterConfiguration {
..Default::default()
},
&|| Segment::empty().fixed("settings", Route::content(comp(Settings)))
);
// ...
# unimplemented!()
}
```
## Defining the nested [`Segment`]
In order to create nested routes we need to create a nested [`Segment`]. We then
pass it to the [`Route`] on the root segment.
> A [`Segment`] always refers to one exact segment of the path.
>
> https://router.example/`root_segment`/`first_nested_segment`/`second_nested_segment`/...
```rust, no_run
# // Hidden lines (like this one) make the documentation tests work.
# extern crate dioxus;
# use dioxus::prelude::*;
# extern crate dioxus_router;
# use dioxus_router::prelude::*;
# fn Settings(cx: Scope) -> Element { unimplemented!() }
# fn GeneralSettings(cx: Scope) -> Element { unimplemented!() }
# fn PWSettings(cx: Scope) -> Element { unimplemented!() }
# fn PrivacySettings(cx: Scope) -> Element { unimplemented!() }
#
fn App(cx: Scope) -> Element {
use_router(
cx,
&|| RouterConfiguration {
..Default::default()
},
&|| Segment::empty().fixed(
"settings",
Route::content(comp(Settings)).nested(
Segment::content(comp(GeneralSettings))
.fixed("password", comp(PWSettings))
.fixed("privacy", comp(PrivacySettings))
)
)
);
// ...
# unimplemented!()
}
```
## Full Code
```rust, no_run
# // Hidden lines (like this one) make the documentation tests work.
# extern crate dioxus;
# use dioxus::prelude::*;
# extern crate dioxus_router;
# use dioxus_router::{history::MemoryHistory, prelude::*};
# extern crate dioxus_ssr;
#
fn Settings(cx: Scope) -> Element {
render! {
h1 { "Settings" }
Outlet { }
}
}
fn GeneralSettings(cx: Scope) -> Element {
render! {
h2 { "General Settings" }
}
}
fn PWSettings(cx: Scope) -> Element {
render! {
h2 { "Password Settings" }
}
}
fn PrivacySettings(cx: Scope) -> Element {
render! {
h2 { "Privacy Settings" }
}
}
fn App(cx: Scope) -> Element {
use_router(
cx,
&|| RouterConfiguration {
# synchronous: true,
# history: Box::new(MemoryHistory::with_initial_path("/settings/privacy").unwrap()),
..Default::default()
},
&|| Segment::empty().fixed(
"settings",
Route::content(comp(Settings)).nested(
Segment::content(comp(GeneralSettings))
.fixed("password", comp(PWSettings))
.fixed("privacy", comp(PrivacySettings))
)
)
);
render! {
Outlet { }
}
}
#
# let mut vdom = VirtualDom::new(App);
# vdom.rebuild();
# assert_eq!(
# dioxus_ssr::render(&vdom),
# "<h1>Settings</h1><h2>Privacy Settings</h2>"
# );
```
[`Outlet`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html
[`Route`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Route.html
[`Segment`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html