mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-23 20:53:06 +00:00
fix book example section
This commit is contained in:
parent
e3610738ab
commit
1890ebc4f7
5 changed files with 147 additions and 155 deletions
|
@ -3,7 +3,7 @@ Not a bird's nest! A nest of routes!
|
||||||
|
|
||||||
In this chapter we will begin to build the blog portion of our site which will
|
In this chapter we will begin to build the blog portion of our site which will
|
||||||
include links, nested URLs, and URL parameters. We will also explore the use
|
include links, nested URLs, and URL parameters. We will also explore the use
|
||||||
case of rendering components directly in the [`Router`].
|
case of rendering components directly in the component calling [`use_router`].
|
||||||
|
|
||||||
## Site Navigation
|
## Site Navigation
|
||||||
Our site visitors won't know all the available pages and blogs on our site so we
|
Our site visitors won't know all the available pages and blogs on our site so we
|
||||||
|
@ -44,7 +44,10 @@ fn NavBar(cx: Scope) -> Element {
|
||||||
nav {
|
nav {
|
||||||
ul {
|
ul {
|
||||||
// new stuff starts here
|
// new stuff starts here
|
||||||
li { Link { target: InternalTarget(String::from("/")), "Home" } }
|
li { Link {
|
||||||
|
target: NavigationTarget::Internal(String::from("/")),
|
||||||
|
"Home"
|
||||||
|
} }
|
||||||
li { Link {
|
li { Link {
|
||||||
target: "/blog", // short form
|
target: "/blog", // short form
|
||||||
"Blog"
|
"Blog"
|
||||||
|
@ -72,18 +75,15 @@ And finally, we add the navbar component in our app component:
|
||||||
# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
||||||
#
|
#
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
let routes = use_segment(&cx, || {
|
use_router(
|
||||||
Segment::new()
|
cx,
|
||||||
.index(Home as Component)
|
&|| RouterConfiguration::default(),
|
||||||
.fallback(PageNotFound as Component)
|
&|| Segment::content(comp(Home)).fallback(comp(PageNotFound))
|
||||||
});
|
);
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
Router {
|
|
||||||
routes: routes.clone(),
|
|
||||||
NavBar { } // this is new
|
NavBar { } // this is new
|
||||||
Outlet { }
|
Outlet { }
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -107,7 +107,7 @@ fn NavBar(cx: Scope) -> Element {
|
||||||
nav {
|
nav {
|
||||||
ul {
|
ul {
|
||||||
li { Link {
|
li { Link {
|
||||||
target: InternalTarget(String::from("/")),
|
target: NavigationTarget::Internal(String::from("/")),
|
||||||
active_class: "active", // this is new
|
active_class: "active", // this is new
|
||||||
"Home"
|
"Home"
|
||||||
} }
|
} }
|
||||||
|
@ -196,10 +196,12 @@ parameters:
|
||||||
# extern crate dioxus_router;
|
# extern crate dioxus_router;
|
||||||
# use dioxus_router::prelude::*;
|
# use dioxus_router::prelude::*;
|
||||||
#
|
#
|
||||||
|
struct PostId;
|
||||||
|
|
||||||
fn BlogPost(cx: Scope) -> Element {
|
fn BlogPost(cx: Scope) -> Element {
|
||||||
let route = use_route(&cx).unwrap();
|
let route = use_route(&cx).unwrap();
|
||||||
|
|
||||||
let post_id = route.parameters.get("post_id");
|
let post_id = route.parameter::<PostId>();
|
||||||
let post = post_id
|
let post = post_id
|
||||||
.map(|id| id.to_string())
|
.map(|id| id.to_string())
|
||||||
.unwrap_or(String::from("unknown"));
|
.unwrap_or(String::from("unknown"));
|
||||||
|
@ -219,34 +221,31 @@ Finally, let's tell our router about those components.
|
||||||
# use dioxus_router::prelude::*;
|
# use dioxus_router::prelude::*;
|
||||||
# fn Blog(cx: Scope) -> Element { unimplemented!() }
|
# fn Blog(cx: Scope) -> Element { unimplemented!() }
|
||||||
# fn BlogList(cx: Scope) -> Element { unimplemented!() }
|
# fn BlogList(cx: Scope) -> Element { unimplemented!() }
|
||||||
|
# struct PostId;
|
||||||
# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
||||||
# fn Home(cx: Scope) -> Element { unimplemented!() }
|
# fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||||
# fn NavBar(cx: Scope) -> Element { unimplemented!() }
|
# fn NavBar(cx: Scope) -> Element { unimplemented!() }
|
||||||
# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
||||||
#
|
#
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
let routes = use_segment(&cx, || {
|
use_router(
|
||||||
Segment::default()
|
cx,
|
||||||
.index(Home as Component)
|
&|| RouterConfiguration::default(),
|
||||||
|
&|| {
|
||||||
|
Segment::content(comp(Home))
|
||||||
// new stuff starts here
|
// new stuff starts here
|
||||||
.fixed(
|
.fixed("blog", Route::content(comp(Blog)).nested(
|
||||||
"blog",
|
Segment::content(comp(BlogList))
|
||||||
Route::new(Blog as Component).nested(
|
.catch_all((comp(BlogPost), PostId { }))
|
||||||
Segment::default()
|
))
|
||||||
.index(BlogList as Component)
|
|
||||||
.catch_all(("post_id", BlogPost as Component))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
// new stuff ends here
|
// new stuff ends here
|
||||||
.fallback(PageNotFound as Component)
|
.fallback(comp(PageNotFound))
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
Router {
|
|
||||||
routes: routes.clone(),
|
|
||||||
NavBar { }
|
NavBar { }
|
||||||
Outlet { }
|
Outlet { }
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -260,4 +259,4 @@ we will go over how navigation targets (like the one we passed to our links)
|
||||||
work.
|
work.
|
||||||
|
|
||||||
[`Link`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html
|
[`Link`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html
|
||||||
[`Router`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Router.html
|
[`use_router`]: https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html
|
||||||
|
|
|
@ -6,27 +6,25 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
let routes = use_segment(&cx, || {
|
use_router(
|
||||||
Segment::default()
|
cx,
|
||||||
.index(Home as Component)
|
&|| RouterConfiguration::default(),
|
||||||
.fixed(
|
&|| {
|
||||||
"blog",
|
Segment::content(comp(Home))
|
||||||
Route::new(Blog as Component).nested(
|
.fixed("blog", Route::content(comp(Blog)).nested(
|
||||||
Segment::default().index(BlogList as Component).catch_all(
|
Segment::content(comp(BlogList)).catch_all(
|
||||||
ParameterRoute::new("post_id", BlogPost as Component).name(BlogPost),
|
ParameterRoute::content::<PostId>(comp(BlogPost))
|
||||||
),
|
.name::<BlogPostName>()
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.fixed("myblog", "/blog")
|
))
|
||||||
.fallback(PageNotFound as Component)
|
.fixed("myblog", "/blog") // this is new
|
||||||
});
|
.fallback(comp(PageNotFound))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
Router {
|
|
||||||
routes: routes.clone(),
|
|
||||||
NavBar {}
|
NavBar {}
|
||||||
Outlet {}
|
Outlet {}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +32,7 @@ fn NavBar(cx: Scope) -> Element {
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
nav {
|
nav {
|
||||||
ul {
|
ul {
|
||||||
li { Link { target: (RootIndex, []), "Home" } }
|
li { Link { target: named::<RootIndex>(), "Home" } }
|
||||||
li { Link { target: "/blog", "Blog" } }
|
li { Link { target: "/blog", "Blog" } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,21 +57,23 @@ fn BlogList(cx: Scope) -> Element {
|
||||||
h2 { "Choose a post" }
|
h2 { "Choose a post" }
|
||||||
ul {
|
ul {
|
||||||
li { Link {
|
li { Link {
|
||||||
target: (BlogPost, [("post_id", String::from("1"))]),
|
target: named::<BlogPostName>().parameter::<PostId>("1"),
|
||||||
"Read the first blog post"
|
"Read the first blog post"
|
||||||
} }
|
} }
|
||||||
li { Link {
|
li { Link {
|
||||||
target: (BlogPost, [("post_id", String::from("2"))]),
|
target: named::<BlogPostName>().parameter::<PostId>("2"),
|
||||||
"Read the second blog post"
|
"Read the second blog post"
|
||||||
} }
|
} }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PostId;
|
||||||
|
struct BlogPostName;
|
||||||
fn BlogPost(cx: Scope) -> Element {
|
fn BlogPost(cx: Scope) -> Element {
|
||||||
let route = use_route(&cx).unwrap();
|
let route = use_route(&cx).unwrap();
|
||||||
|
|
||||||
let post_id = route.parameters.get("post_id");
|
let post_id = route.parameter::<PostId>();
|
||||||
let post = post_id
|
let post = post_id
|
||||||
.map(|id| id.to_string())
|
.map(|id| id.to_string())
|
||||||
.unwrap_or(String::from("unknown"));
|
.unwrap_or(String::from("unknown"));
|
||||||
|
|
|
@ -3,9 +3,9 @@ In this chapter, we will start utilizing Dioxus Router and add a homepage and a
|
||||||
404 page to our project.
|
404 page to our project.
|
||||||
|
|
||||||
## Fundamentals
|
## Fundamentals
|
||||||
Dioxus Router works based on a [`Router`] component, a route definition in
|
Dioxus Router works based on a [`use_router`] hook, a route definition in pure
|
||||||
regular rust and [`Outlet`] components. If you've ever used [Vue Router],
|
rust and [`Outlet`] components. If you've ever used [Vue Router], you should
|
||||||
you should feel at home with Dioxus Router.
|
feel right at home with Dioxus Router.
|
||||||
|
|
||||||
First we need an actual page to route to! Let's add a homepage component:
|
First we need an actual page to route to! Let's add a homepage component:
|
||||||
```rust,no_run
|
```rust,no_run
|
||||||
|
@ -24,12 +24,16 @@ fn Home(cx: Scope) -> Element {
|
||||||
We want to use Dioxus Router to separate our application into different "pages".
|
We want to use Dioxus Router to separate our application into different "pages".
|
||||||
Dioxus Router will then determine which page to render based on the URL path.
|
Dioxus Router will then determine which page to render based on the URL path.
|
||||||
|
|
||||||
To start using Dioxus Router, we need to use the [`Router`] component. All hooks
|
To start using Dioxus Router, we need to use the [`use_router`] hook. All other
|
||||||
and other components the Router provides can only be used as a descendant of
|
hooks and components the router provides can only be used as a descendant of a
|
||||||
a [`Router`] component.
|
component calling [`use_router`].
|
||||||
|
|
||||||
|
The [`use_router`] hook takes three arguments:
|
||||||
|
1. `cx`, which is a common argument for all hooks.
|
||||||
|
2. A [`RouterConfiguration`], which allows us to modify its behavior.
|
||||||
|
3. A definition of all routes the application contains, in the form of its root
|
||||||
|
[`Segment`].
|
||||||
|
|
||||||
However, before we can add the [`Router`] we need to describe our routes in a
|
|
||||||
type it can understand:
|
|
||||||
```rust,no_run
|
```rust,no_run
|
||||||
# // Hidden lines (like this one) make the documentation tests work.
|
# // Hidden lines (like this one) make the documentation tests work.
|
||||||
# extern crate dioxus;
|
# extern crate dioxus;
|
||||||
|
@ -39,40 +43,14 @@ use dioxus_router::prelude::*;
|
||||||
# fn Home(cx: Scope) -> Element { unimplemented!() }
|
# fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
let routes = use_segment(&cx, || {
|
use_router(
|
||||||
// we want our home page component to render as an index
|
cx,
|
||||||
Segment::default().index(Home as Component)
|
&|| RouterConfiguration::default(),
|
||||||
});
|
&|| Segment::content(comp(Home))
|
||||||
|
);
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
p { "Hello, Dioxus!"}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Now we can replace the `p { "Hello, Dioxus!" }` with our [`Router`]. We also
|
|
||||||
need to tell it where to render the content of the active route. Therefore we
|
|
||||||
nest an [`Outlet`] inside it.
|
|
||||||
```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 Home(cx: Scope) -> Element { unimplemented!() }
|
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
|
||||||
let routes = use_segment(&cx, || {
|
|
||||||
Segment::default().index(Home as Component)
|
|
||||||
});
|
|
||||||
|
|
||||||
cx.render(rsx! {
|
|
||||||
// new stuff starts here
|
|
||||||
Router {
|
|
||||||
routes: routes.clone() // pass in the routes we prepared before
|
|
||||||
Outlet { }
|
Outlet { }
|
||||||
}
|
|
||||||
// new stuff ends here
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -82,8 +60,8 @@ If you head to your application's browser tab, you should now see the text
|
||||||
you enter a different path for the URL, nothing should be displayed.
|
you enter a different path for the URL, nothing should be displayed.
|
||||||
|
|
||||||
This is because we told Dioxus Router to render the `Home` component only when
|
This is because we told Dioxus Router to render the `Home` component only when
|
||||||
the URL path is `/`. The _index_ functionality we used basically emulates how
|
the URL path is `/`. The _index_ (`Segment::content()`) functionality we used
|
||||||
web servers treat `index.html` files.
|
basically emulates how web servers treat `index.html` files.
|
||||||
|
|
||||||
## What if a Route Doesn't Exist?
|
## What if a Route Doesn't Exist?
|
||||||
In our example Dioxus Router doesn't render anything. Many sites also have a
|
In our example Dioxus Router doesn't render anything. Many sites also have a
|
||||||
|
@ -114,17 +92,17 @@ Now to tell Dioxus Router to render our new component when no route exists.
|
||||||
# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
||||||
#
|
#
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
let routes = use_segment(&cx, || {
|
use_router(
|
||||||
Segment::default()
|
cx,
|
||||||
.index(Home as Component)
|
&|| RouterConfiguration::default(),
|
||||||
.fallback(PageNotFound as Component) // this is new
|
&|| {
|
||||||
});
|
Segment::content(comp(Home))
|
||||||
|
.fallback(comp(PageNotFound)) // this is new
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
Router {
|
|
||||||
routes: routes.clone(),
|
|
||||||
Outlet { }
|
Outlet { }
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -139,5 +117,7 @@ handle when a route doesn't exist. Next, we'll create the blog portion of our
|
||||||
site. We will utilize nested routes and URL parameters.
|
site. We will utilize nested routes and URL parameters.
|
||||||
|
|
||||||
[`Outlet`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html
|
[`Outlet`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html
|
||||||
[`Router`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Router.html
|
[`RouterConfiguration`]: https://docs.rs/dioxus-router/latest/dioxus_router/hooks/struct.RouterConfiguration.html
|
||||||
|
[`Segment`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html
|
||||||
|
[`use_router`]: https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html
|
||||||
[Vue Router]: https://router.vuejs.org/
|
[Vue Router]: https://router.vuejs.org/
|
||||||
|
|
|
@ -7,12 +7,12 @@ We told them where to go using the `target` property. This property takes a
|
||||||
A [`NavigationTarget`] is similar to the `href` of an HTML anchor element.It
|
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
|
tells the router where to navigate to. The Dioxus Router knows three kinds of
|
||||||
navigation targets:
|
navigation targets:
|
||||||
- [`InternalTarget`]: we already saw that. It's basically an `href`, but cannot
|
- [`Internal`]: we already saw that. It's basically an `href`, but cannot
|
||||||
link to content outside our app.
|
link to content outside our app.
|
||||||
- [`ExternalTarget`]: This works exactly like an HTML anchors `href`. In fact,
|
- [`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
|
it is just passed through. Don't use this for in-app navigation as it'll
|
||||||
trigger a page reload by the browser.
|
trigger a page reload by the browser.
|
||||||
- [`NamedTarget`]: this is the most interesting form of navigation target. We'll look
|
- [`Named`]: this is the most interesting form of navigation target. We'll look
|
||||||
at it in detail in this chapter.
|
at it in detail in this chapter.
|
||||||
|
|
||||||
## External navigation
|
## External navigation
|
||||||
|
@ -27,7 +27,7 @@ If we need a link to an external page we can do it like this:
|
||||||
fn GoToDioxus(cx: Scope) -> Element {
|
fn GoToDioxus(cx: Scope) -> Element {
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
Link {
|
Link {
|
||||||
target: ExternalTarget(String::from("https://dioxuslabs.com")),
|
target: NavigationTarget::External("https://dioxuslabs.com".into()),
|
||||||
"Explicit ExternalTarget target"
|
"Explicit ExternalTarget target"
|
||||||
}
|
}
|
||||||
Link {
|
Link {
|
||||||
|
@ -38,8 +38,8 @@ fn GoToDioxus(cx: Scope) -> Element {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> Note that we can use a `str`, just like with [`InternalTarget`]s. The router
|
> Note that we can use a `str`, just like with [`Internal`]s. The router will
|
||||||
> will convert a `str` to an [`ExternalTarget`] if the URL is absolute.
|
> convert a `str` to an [`External`] if the URL is absolute.
|
||||||
|
|
||||||
## Named navigation
|
## Named navigation
|
||||||
When defining our routes, we can optionally give them unique static names. This
|
When defining our routes, we can optionally give them unique static names. This
|
||||||
|
@ -50,9 +50,10 @@ named navigation we instead give it a name, and let it figure out the path.
|
||||||
|
|
||||||
This has several advantages:
|
This has several advantages:
|
||||||
- We don't have to remember absolute paths or care about what the current path
|
- We don't have to remember absolute paths or care about what the current path
|
||||||
is
|
is.
|
||||||
- changing paths later on won't break internal links
|
- Changing paths later on won't break internal links.
|
||||||
- paths can easily be localized without affecting app logic
|
- 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
|
Let's try that now! First, we give our blog post route a name. We can reuse our
|
||||||
`BlogPost` component as a name.
|
`BlogPost` component as a name.
|
||||||
|
@ -64,23 +65,28 @@ Let's try that now! First, we give our blog post route a name. We can reuse our
|
||||||
# use dioxus_router::prelude::*;
|
# use dioxus_router::prelude::*;
|
||||||
# fn Blog(cx: Scope) -> Element { unimplemented!() }
|
# fn Blog(cx: Scope) -> Element { unimplemented!() }
|
||||||
# fn BlogList(cx: Scope) -> Element { unimplemented!() }
|
# fn BlogList(cx: Scope) -> Element { unimplemented!() }
|
||||||
|
# struct PostId;
|
||||||
# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
||||||
# fn Home(cx: Scope) -> Element { unimplemented!() }
|
# fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||||
|
# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
||||||
#
|
#
|
||||||
|
struct BlogPostName;
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
let routes = use_segment(&cx, || {
|
use_router(
|
||||||
Segment::default()
|
cx,
|
||||||
.index(Home as Component)
|
&|| RouterConfiguration::default(),
|
||||||
.fixed(
|
&|| {
|
||||||
"blog",
|
Segment::content(comp(Home))
|
||||||
Route::new(Blog as Component).nested(
|
.fixed("blog", Route::content(comp(Blog)).nested(
|
||||||
Segment::default().index(BlogList as Component).catch_all(
|
Segment::content(comp(BlogList)).catch_all(
|
||||||
// notice the name at the end of the line
|
ParameterRoute::content::<PostId>(comp(BlogPost))
|
||||||
ParameterRoute::new("post_id", BlogPost as Component).name(BlogPost),
|
.name::<BlogPostName>() // this is new
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
});
|
))
|
||||||
|
.fallback(comp(PageNotFound))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
# unimplemented!()
|
# unimplemented!()
|
||||||
|
@ -94,6 +100,8 @@ Now we can change the targets of the links in our `BlogList` component.
|
||||||
# use dioxus::prelude::*;
|
# use dioxus::prelude::*;
|
||||||
# extern crate dioxus_router;
|
# extern crate dioxus_router;
|
||||||
# use dioxus_router::prelude::*;
|
# use dioxus_router::prelude::*;
|
||||||
|
# struct PostId;
|
||||||
|
# struct BlogPostName;
|
||||||
# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
||||||
#
|
#
|
||||||
fn BlogList(cx: Scope) -> Element {
|
fn BlogList(cx: Scope) -> Element {
|
||||||
|
@ -101,11 +109,13 @@ fn BlogList(cx: Scope) -> Element {
|
||||||
h2 { "Choose a post" }
|
h2 { "Choose a post" }
|
||||||
ul {
|
ul {
|
||||||
li { Link {
|
li { Link {
|
||||||
target: (BlogPost, [("post_id", String::from("1"))]),
|
target: named::<BlogPostName>().parameter::<PostId>("1"),
|
||||||
"Read the first blog post"
|
"Read the first blog post"
|
||||||
} }
|
} }
|
||||||
li { Link {
|
li { Link {
|
||||||
target: (BlogPost, [("post_id", String::from("2"))], "query"),
|
target: named::<BlogPostName>()
|
||||||
|
.parameter::<PostId>("1")
|
||||||
|
.query("query"),
|
||||||
"Read the second blog post"
|
"Read the second blog post"
|
||||||
} }
|
} }
|
||||||
}
|
}
|
||||||
|
@ -113,7 +123,7 @@ fn BlogList(cx: Scope) -> Element {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
As you can see, a [`NamedTarget`] requires three fields:
|
As you can see, a [`Named`] requires three fields:
|
||||||
1. the name to navigate to
|
1. the name to navigate to
|
||||||
2. a `Vec` containing all parameters that need to be inserted into the path
|
2. a `Vec` containing all parameters that need to be inserted into the path
|
||||||
3. optionally a query string to use.
|
3. optionally a query string to use.
|
||||||
|
@ -135,7 +145,7 @@ fn NavBar(cx: Scope) -> Element {
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
nav {
|
nav {
|
||||||
ul {
|
ul {
|
||||||
li { Link { target: (RootIndex, []), "Home" } }
|
li { Link { target: named::<RootIndex>(), "Home" } }
|
||||||
li { Link { target: "/blog", "Blog" } }
|
li { Link { target: "/blog", "Blog" } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,8 +154,8 @@ fn NavBar(cx: Scope) -> Element {
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
[`ExternalTarget`]: https://docs.rs/dioxus-router/latest/dioxus_router/navigation/enum.NavigationTarget.html#variant.ExternalTarget
|
[`External`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External
|
||||||
[`InternalTarget`]: https://docs.rs/dioxus-router/latest/dioxus_router/navigation/enum.NavigationTarget.html#variant.InternalTarget
|
[`Internal`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal
|
||||||
[`NamedTarget`]: https://docs.rs/dioxus-router/latest/dioxus_router/navigation/enum.NavigationTarget.html#variant.NamedTarget
|
[`Named`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named
|
||||||
[`NavigationTarget`]: https://docs.rs/dioxus-router/latest/dioxus_router/navigation/enum.NavigationTarget.html
|
[`NavigationTarget`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html
|
||||||
[`RootIndex`]: https://docs.rs/dioxus-router/latest/dioxus_router/names/struct.RootIndex.html
|
[`RootIndex`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/prelude/struct.RootIndex.html
|
||||||
|
|
|
@ -21,25 +21,28 @@ All we need to do is update our route definition in our app component:
|
||||||
# use dioxus_router::prelude::*;
|
# use dioxus_router::prelude::*;
|
||||||
# fn Blog(cx: Scope) -> Element { unimplemented!() }
|
# fn Blog(cx: Scope) -> Element { unimplemented!() }
|
||||||
# fn BlogList(cx: Scope) -> Element { unimplemented!() }
|
# fn BlogList(cx: Scope) -> Element { unimplemented!() }
|
||||||
|
# struct PostId;
|
||||||
|
# struct BlogPostName;
|
||||||
# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
|
||||||
# fn Home(cx: Scope) -> Element { unimplemented!() }
|
# fn Home(cx: Scope) -> Element { unimplemented!() }
|
||||||
# fn NavBar(cx: Scope) -> Element { unimplemented!() }
|
# fn NavBar(cx: Scope) -> Element { unimplemented!() }
|
||||||
# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
|
||||||
# fn App(cx: Scope) -> Element {
|
# fn App(cx: Scope) -> Element {
|
||||||
let routes = use_segment(&cx, || {
|
use_router(
|
||||||
Segment::new()
|
cx,
|
||||||
.index(Home as Component)
|
&|| RouterConfiguration::default(),
|
||||||
.fixed(
|
&|| {
|
||||||
"blog",
|
Segment::content(comp(Home))
|
||||||
Route::new(Blog as Component).nested(
|
.fixed("blog", Route::content(comp(Blog)).nested(
|
||||||
Segment::new().index(BlogList as Component).catch_all(
|
Segment::content(comp(BlogList)).catch_all(
|
||||||
ParameterRoute::new("post_id", BlogPost as Component).name(BlogPost)
|
ParameterRoute::content::<PostId>(comp(BlogPost))
|
||||||
),
|
.name::<BlogPostName>()
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
))
|
||||||
.fixed("myblog", "/blog") // this is new
|
.fixed("myblog", "/blog") // this is new
|
||||||
.fallback(PageNotFound as Component)
|
.fallback(comp(PageNotFound))
|
||||||
});
|
}
|
||||||
|
);
|
||||||
# unimplemented!()
|
# unimplemented!()
|
||||||
# }
|
# }
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in a new issue