simple_routes.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #![allow(non_snake_case)]
  2. use dioxus::prelude::*;
  3. use dioxus_router::prelude::*;
  4. use serde::{Deserialize, Serialize};
  5. use std::str::FromStr;
  6. fn main() {
  7. #[cfg(not(target_arch = "wasm32"))]
  8. dioxus_desktop::launch(root);
  9. #[cfg(target_arch = "wasm32")]
  10. dioxus_web::launch(root);
  11. }
  12. fn root(cx: Scope) -> Element {
  13. render! {
  14. Router {
  15. config: RouterConfiguration {
  16. history: {
  17. #[cfg(not(target_arch = "wasm32"))]
  18. let history = Box::<MemoryHistory::<Route>>::default();
  19. #[cfg(target_arch = "wasm32")]
  20. let history = Box::<WebHistory::<Route>>::default();
  21. history
  22. },
  23. ..Default::default()
  24. }
  25. }
  26. }
  27. }
  28. #[inline_props]
  29. fn UserFrame(cx: Scope, user_id: usize) -> Element {
  30. render! {
  31. pre {
  32. "UserFrame{{\n\tuser_id:{user_id}\n}}"
  33. }
  34. div {
  35. background_color: "rgba(0,0,0,50%)",
  36. "children:"
  37. Outlet {}
  38. }
  39. }
  40. }
  41. #[inline_props]
  42. fn Route1(cx: Scope, user_id: usize, dynamic: usize, query: String, extra: String) -> Element {
  43. render! {
  44. pre {
  45. "Route1{{\n\tuser_id:{user_id},\n\tdynamic:{dynamic},\n\tquery:{query},\n\textra:{extra}\n}}"
  46. }
  47. Link {
  48. target: Route::Route1 { user_id: *user_id, dynamic: *dynamic, query: String::new(), extra: extra.clone() + "." },
  49. "Route1 with extra+\".\""
  50. }
  51. p { "Footer" }
  52. Link {
  53. target: Route::Route3 { dynamic: String::new() },
  54. "Home"
  55. }
  56. }
  57. }
  58. #[inline_props]
  59. fn Route2(cx: Scope, user_id: usize) -> Element {
  60. render! {
  61. pre {
  62. "Route2{{\n\tuser_id:{user_id}\n}}"
  63. }
  64. (0..*user_id).map(|i| rsx!{ p { "{i}" } }),
  65. p { "Footer" }
  66. Link {
  67. target: Route::Route3 { dynamic: String::new() },
  68. "Home"
  69. }
  70. }
  71. }
  72. #[inline_props]
  73. fn Route3(cx: Scope, dynamic: String) -> Element {
  74. let navigator = use_navigator(cx);
  75. let current_route = use_route(cx)?;
  76. let current_route_str = use_ref(cx, String::new);
  77. let parsed = Route::from_str(&current_route_str.read());
  78. let site_map = Route::SITE_MAP
  79. .iter()
  80. .flat_map(|seg| seg.flatten().into_iter())
  81. .collect::<Vec<_>>();
  82. render! {
  83. input {
  84. oninput: move |evt| {
  85. *current_route_str.write() = evt.value.clone();
  86. },
  87. value: "{current_route_str.read()}"
  88. }
  89. "dynamic: {dynamic}"
  90. Link {
  91. target: Route::Route2 { user_id: 8888 },
  92. "hello world link"
  93. }
  94. button {
  95. onclick: move |_| { navigator.push(NavigationTarget::External("https://www.google.com".to_string())); },
  96. "google link"
  97. }
  98. p { "Site Map" }
  99. pre { "{site_map:#?}" }
  100. p { "Dynamic link" }
  101. if let Ok(route) = parsed {
  102. if route != current_route {
  103. render! {
  104. Link {
  105. target: route.clone(),
  106. "{route}"
  107. }
  108. }
  109. }
  110. else {
  111. None
  112. }
  113. }
  114. else {
  115. None
  116. }
  117. }
  118. }
  119. #[rustfmt::skip]
  120. #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Routable)]
  121. enum Route {
  122. // Nests with parameters have types taken from child routes
  123. #[nest("/user/:user_id")]
  124. // Everything inside the nest has the added parameter `user_id: String`
  125. // UserFrame is a layout component that will receive the `user_id: String` parameter
  126. #[layout(UserFrame)]
  127. // Route1 is a non-layout component that will receive the `user_id: String` and `dynamic: String` parameters
  128. #[route("/:dynamic?:query")]
  129. Route1 {
  130. // The type is taken from the first instance of the dynamic parameter
  131. user_id: usize,
  132. dynamic: usize,
  133. query: String,
  134. extra: String,
  135. },
  136. // Route2 is a non-layout component that will receive the `user_id: String` parameter
  137. #[route("/hello_world")]
  138. // You can opt out of the layout by using the `!` prefix
  139. #[layout(!UserFrame)]
  140. Route2 { user_id: usize },
  141. #[end_layout]
  142. #[end_nest]
  143. #[redirect("/:id/user", |id: usize| Route::Route3 { dynamic: id.to_string()})]
  144. #[route("/:dynamic")]
  145. Route3 { dynamic: String },
  146. }