add: some basic FE/BE interaction

This commit is contained in:
2025-05-01 23:12:29 -07:00
parent 8cfa9d2716
commit 88b0d26b36
3 changed files with 61 additions and 19 deletions

View File

@@ -9,7 +9,7 @@ crate-type = ["cdylib", "rlib"]
[dependencies] [dependencies]
leptos = { version = "0.7.0", features = ["nightly"] } leptos = { version = "0.7.0", features = ["nightly"] }
leptos_router = { version = "0.7.0", features = ["nightly"] } leptos_router = { version = "0.7.0", features = ["nightly"] }
axum = { version = "0.7", optional = true } axum = { version = "0.7", optional = true, features = ["macros"] }
console_error_panic_hook = { version = "0.1", optional = true} console_error_panic_hook = { version = "0.1", optional = true}
leptos_axum = { version = "0.7.0", optional = true } leptos_axum = { version = "0.7.0", optional = true }
leptos_meta = { version = "0.7.0" } leptos_meta = { version = "0.7.0" }

View File

@@ -1,4 +1,4 @@
use leptos::prelude::*; use leptos::{prelude::*, task::spawn_local};
use leptos_meta::{provide_meta_context, MetaTags, Stylesheet, Title}; use leptos_meta::{provide_meta_context, MetaTags, Stylesheet, Title};
use leptos_router::{ use leptos_router::{
components::{Route, Router, Routes}, components::{Route, Router, Routes},
@@ -23,6 +23,26 @@ pub fn shell(options: LeptosOptions) -> impl IntoView {
} }
} }
#[server]
pub async fn load_counter() -> Result<usize, ServerFnError> {
use tokio::sync::Mutex;
use std::sync::Arc;
let data = use_context::<Arc<Mutex<usize>>>().unwrap();
let mut data = data.lock().await;
Ok(*data)
}
#[server]
pub async fn increment_counter() -> Result<usize, ServerFnError> {
use tokio::sync::Mutex;
use std::sync::Arc;
let data = use_context::<Arc<Mutex<usize>>>().unwrap();
let mut data = data.lock().await;
*data += 1;
println!("Counter {}", *data);
Ok(*data)
}
#[component] #[component]
pub fn App() -> impl IntoView { pub fn App() -> impl IntoView {
// Provides context that manages stylesheets, titles, meta tags, etc. // Provides context that manages stylesheets, titles, meta tags, etc.
@@ -50,12 +70,33 @@ pub fn App() -> impl IntoView {
/// Renders the home page of your application. /// Renders the home page of your application.
#[component] #[component]
fn HomePage() -> impl IntoView { fn HomePage() -> impl IntoView {
// Creates a reactive value to update the button let increment_counter = ServerAction::<IncrementCounter>::new();
let count = RwSignal::new(0); let counts = Resource::new(
let on_click = move |_| *count.write() += 1; move || {
(
increment_counter.version().get(),
)
},
move |_| load_counter()
);
let existing_counter = move || {
Suspend::new(async move {
let count = counts.await;
view! { {count} }
})
};
let onclick = move |ev| {
increment_counter.dispatch(IncrementCounter{});
};
view! { view! {
<h1>"Welcome to Leptos!"</h1> <h1>"Welcome to Leptos!"</h1>
<button on:click=on_click>"Click Me: " {count}</button> <button on:click=onclick>"Click Me: "
<Transition fallback=move || view! { <p>"Loading..."</p> }>
{existing_counter}
</Transition>
</button>
} }
} }

View File

@@ -1,7 +1,8 @@
//#[cfg(feature = "ssr")]
#[cfg(feature = "ssr")]
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
use std::sync::Arc;
use tokio::sync::Mutex;
use axum::Router; use axum::Router;
use leptos::logging::log; use leptos::logging::log;
use leptos::prelude::*; use leptos::prelude::*;
@@ -14,11 +15,18 @@ async fn main() {
// Generate the list of routes in your Leptos App // Generate the list of routes in your Leptos App
let routes = generate_route_list(App); let routes = generate_route_list(App);
let counter: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
let app = Router::new() let app = Router::new()
.leptos_routes(&leptos_options, routes, { .leptos_routes_with_context(
&leptos_options,
routes,
move || provide_context(counter.clone()),
{
let leptos_options = leptos_options.clone(); let leptos_options = leptos_options.clone();
move || shell(leptos_options.clone()) move || shell(leptos_options.clone())
}) },
)
.fallback(leptos_axum::file_and_error_handler(shell)) .fallback(leptos_axum::file_and_error_handler(shell))
.with_state(leptos_options); .with_state(leptos_options);
@@ -30,10 +38,3 @@ async fn main() {
.await .await
.unwrap(); .unwrap();
} }
#[cfg(not(feature = "ssr"))]
pub fn main() {
// no client-side main function
// unless we want this to work with e.g., Trunk for pure client-side testing
// see lib.rs for hydration function instead
}