mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-26 22:20:19 +00:00
More WIP router implementation
This commit is contained in:
parent
c9408da731
commit
e06eac1ce5
2 changed files with 40 additions and 18 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus::router::{Link, Route, Router};
|
||||
use serde::Deserialize;
|
||||
|
||||
fn main() {
|
||||
dioxus::desktop::launch(app);
|
||||
|
@ -30,7 +31,7 @@ fn app(cx: Scope) -> Element {
|
|||
}
|
||||
|
||||
fn BlogPost(cx: Scope) -> Element {
|
||||
let post = dioxus::router::use_route(&cx).last_segment()?;
|
||||
let post = dioxus::router::use_route(&cx).last_segment();
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
@ -40,9 +41,14 @@ fn BlogPost(cx: Scope) -> Element {
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Query {
|
||||
bold: bool,
|
||||
}
|
||||
|
||||
fn User(cx: Scope) -> Element {
|
||||
let post = dioxus::router::use_route(&cx).last_segment()?;
|
||||
let bold = dioxus::router::use_route(&cx).param::<bool>("bold");
|
||||
let post = dioxus::router::use_route(&cx).last_segment();
|
||||
let query = dioxus::router::use_route(&cx).query::<Query>();
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
|
|
@ -1,20 +1,29 @@
|
|||
use dioxus_core::ScopeState;
|
||||
use gloo::history::Location;
|
||||
use gloo::history::{HistoryResult, Location};
|
||||
use serde::de::DeserializeOwned;
|
||||
use std::{rc::Rc, str::FromStr};
|
||||
|
||||
use crate::RouterService;
|
||||
|
||||
pub struct UseRoute<'a> {
|
||||
/// This struct provides is a wrapper around the internal router
|
||||
/// implementation, with methods for getting information about the current
|
||||
/// route.
|
||||
pub struct UseRoute {
|
||||
router: Rc<RouterService>,
|
||||
cx: &'a ScopeState,
|
||||
}
|
||||
|
||||
impl<'a> UseRoute<'a> {
|
||||
/// Parse the query part of the URL
|
||||
pub fn param<T>(&self, param: &str) -> Option<&T> {
|
||||
todo!()
|
||||
impl UseRoute {
|
||||
/// This method simply calls the [`Location::query`] method.
|
||||
pub fn query<T>(&self) -> HistoryResult<T>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
self.current_location().query::<T>()
|
||||
}
|
||||
|
||||
/// Returns the nth segment in the path. Paths that end with a slash have
|
||||
/// the slash removed before determining the segments. If the path has
|
||||
/// fewer segments than `n` then this method returns `None`.
|
||||
pub fn nth_segment(&self, n: usize) -> Option<String> {
|
||||
let mut segments = self.path_segments();
|
||||
let len = segments.len();
|
||||
|
@ -24,13 +33,12 @@ impl<'a> UseRoute<'a> {
|
|||
Some(segments.remove(n))
|
||||
}
|
||||
|
||||
pub fn last_segment(&self) -> Option<String> {
|
||||
/// Returns the last segment in the path. Paths that end with a slash have
|
||||
/// the slash removed before determining the segments. The root path, `/`,
|
||||
/// will return an empty string.
|
||||
pub fn last_segment(&self) -> String {
|
||||
let mut segments = self.path_segments();
|
||||
let len = segments.len();
|
||||
if len == 0 {
|
||||
return None;
|
||||
}
|
||||
Some(segments.remove(len - 1))
|
||||
segments.remove(segments.len() - 1)
|
||||
}
|
||||
|
||||
/// Get the named parameter from the path, as defined in your router. The
|
||||
|
@ -47,21 +55,29 @@ impl<'a> UseRoute<'a> {
|
|||
.and_then(|v| Some(v.parse::<T>()))
|
||||
}
|
||||
|
||||
/// Returns the [Location] for the current route.
|
||||
pub fn current_location(&self) -> Location {
|
||||
self.router.current_location()
|
||||
}
|
||||
|
||||
fn path_segments(&self) -> Vec<String> {
|
||||
let location = self.router.current_location();
|
||||
let path = location.path();
|
||||
if path == "/" {
|
||||
return vec![String::new()];
|
||||
}
|
||||
let stripped = &location.path()[1..];
|
||||
stripped.split('/').map(str::to_string).collect::<Vec<_>>()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn use_route<'a>(cx: &'a ScopeState) -> UseRoute<'a> {
|
||||
/// This hook provides access to information about the current location in the
|
||||
/// context of a [`Router`]. If this function is called outside of a `Router`
|
||||
/// component it will panic.
|
||||
pub fn use_route(cx: &ScopeState) -> UseRoute {
|
||||
let router = cx
|
||||
.consume_context::<RouterService>()
|
||||
.expect("Cannot call use_route outside the scope of a Router component")
|
||||
.clone();
|
||||
UseRoute { router, cx }
|
||||
UseRoute { router }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue