update the router guide
This commit is contained in:
1 parent
67992f7da9
commit
0d3ea377ce
63 files changed
+615
-1705
No files matched your search
@@ -1,161 +1,27 @@
|
||||
# Navigation Targets
|
||||
In the previous chapter we learned how to create links to pages within our app.
|
||||
We told them where to go using the `target` property. This property takes a
|
||||
[`NavigationTarget`].
|
||||
|
||||
In the previous chapter, we learned how to create links to pages within our app.
|
||||
We told them where to go using the `target` property. This property takes something that can be converted to a [`NavigationTarget`].
|
||||
|
||||
## What is a navigation target?
|
||||
A [`NavigationTarget`] is similar to the `href` of an HTML anchor element.It
|
||||
tells the router where to navigate to. The Dioxus Router knows three kinds of
|
||||
|
||||
A [`NavigationTarget`] is similar to the `href` of an HTML anchor element. It
|
||||
tells the router where to navigate to. The Dioxus Router knows two kinds of
|
||||
navigation targets:
|
||||
- [`Internal`]: we already saw that. It's basically an `href`, but cannot
|
||||
link to content outside our app.
|
||||
- [`External`]: This works exactly like an HTML anchors `href`. In fact,
|
||||
it is just passed through. Don't use this for in-app navigation as it'll
|
||||
trigger a page reload by the browser.
|
||||
- [`Named`]: this is the most interesting form of navigation target. We'll look
|
||||
at it in detail in this chapter.
|
||||
|
||||
- [`Internal`]: We used internal links in the previous chapter. It's a link to a page within our
|
||||
app represented as a Route enum.
|
||||
- [`External`]: This works exactly like an HTML anchors' `href`. Don't use this for in-app
|
||||
navigation as it will trigger a page reload by the browser.
|
||||
|
||||
## External navigation
|
||||
|
||||
If we need a link to an external page we can do it like this:
|
||||
```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 GoToDioxus(cx: Scope) -> Element {
|
||||
render! {
|
||||
Link {
|
||||
target: NavigationTarget::External("https://dioxuslabs.com".into()),
|
||||
"Explicit ExternalTarget target"
|
||||
}
|
||||
Link {
|
||||
target: "https://dioxuslabs.com", // short form
|
||||
"Implicit ExternalTarget target"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```rust, no_run
|
||||
{{#include ../../examples/external_link.rs:component}}
|
||||
```
|
||||
|
||||
> Note that we can use a `str`, just like with [`Internal`]s. The router will
|
||||
> convert a `str` to an [`External`] if the URL is absolute.
|
||||
|
||||
## Named navigation
|
||||
When defining our routes, we can optionally give them unique static names. This
|
||||
is required for a feature we call named navigation.
|
||||
|
||||
Up to now, when creating links we told the router the exact path to go to. With
|
||||
named navigation we instead give it a name, and let it figure out the path.
|
||||
|
||||
This has several advantages:
|
||||
- We don't have to remember absolute paths or care about what the current path
|
||||
is.
|
||||
- Changing paths later on won't break internal links.
|
||||
- Paths can easily be localized without affecting app logic.
|
||||
- The compiler makes sure we don't have typos.
|
||||
|
||||
Let's try that now! First, we give our blog post route a name. We can reuse our
|
||||
`BlogPost` component as a name.
|
||||
```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 Blog(cx: Scope) -> Element { unimplemented!() }
|
||||
# fn BlogList(cx: Scope) -> Element { unimplemented!() }
|
||||
# struct PostId;
|
||||
# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
||||
# fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||
# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
||||
#
|
||||
struct BlogPostName;
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_router(
|
||||
cx,
|
||||
&|| RouterConfiguration::default(),
|
||||
&|| {
|
||||
Segment::content(comp(Home))
|
||||
.fixed("blog", Route::content(comp(Blog)).nested(
|
||||
Segment::content(comp(BlogList)).catch_all(
|
||||
ParameterRoute::content::<PostId>(comp(BlogPost))
|
||||
.name::<BlogPostName>() // this is new
|
||||
)
|
||||
))
|
||||
.fallback(comp(PageNotFound))
|
||||
}
|
||||
);
|
||||
|
||||
// ...
|
||||
# unimplemented!()
|
||||
}
|
||||
```
|
||||
|
||||
Now we can change the targets of the links in our `BlogList` component.
|
||||
```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::*;
|
||||
# struct PostId;
|
||||
# struct BlogPostName;
|
||||
# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
||||
#
|
||||
fn BlogList(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Choose a post" }
|
||||
ul {
|
||||
li { Link {
|
||||
target: named::<BlogPostName>().parameter::<PostId>("1"),
|
||||
"Read the first blog post"
|
||||
} }
|
||||
li { Link {
|
||||
target: named::<BlogPostName>()
|
||||
.parameter::<PostId>("1")
|
||||
.query("query"),
|
||||
"Read the second blog post"
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, a [`Named`] requires three fields:
|
||||
1. the name to navigate to
|
||||
2. a `Vec` containing all parameters that need to be inserted into the path
|
||||
3. optionally a query string to use.
|
||||
|
||||
|
||||
### The special root index name
|
||||
Whether we define any names or not, the router always knows about the
|
||||
[`RootIndex`] name. Navigating to it tells the router to go to `/`.
|
||||
|
||||
We can change the link in our `NavBar` component to take advantage of that.
|
||||
```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 NavBar(cx: Scope) -> Element {
|
||||
render! {
|
||||
nav {
|
||||
ul {
|
||||
li { Link { target: named::<RootIndex>(), "Home" } }
|
||||
li { Link { target: "/blog", "Blog" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
[`External`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External
|
||||
[`Internal`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal
|
||||
[`Named`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named
|
||||
[`NavigationTarget`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html
|
||||
[`RootIndex`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/prelude/struct.RootIndex.html
|
||||
Reference in new issue
Block a user