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]
leptos = { 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}
leptos_axum = { version = "0.7.0", optional = true }
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_router::{
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]
pub fn App() -> impl IntoView {
// 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.
#[component]
fn HomePage() -> impl IntoView {
// Creates a reactive value to update the button
let count = RwSignal::new(0);
let on_click = move |_| *count.write() += 1;
let increment_counter = ServerAction::<IncrementCounter>::new();
let counts = Resource::new(
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! {
<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]
async fn main() {
use std::sync::Arc;
use tokio::sync::Mutex;
use axum::Router;
use leptos::logging::log;
use leptos::prelude::*;
@@ -14,11 +15,18 @@ async fn main() {
// Generate the list of routes in your Leptos App
let routes = generate_route_list(App);
let counter: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
let app = Router::new()
.leptos_routes(&leptos_options, routes, {
let leptos_options = leptos_options.clone();
move || shell(leptos_options.clone())
})
.leptos_routes_with_context(
&leptos_options,
routes,
move || provide_context(counter.clone()),
{
let leptos_options = leptos_options.clone();
move || shell(leptos_options.clone())
},
)
.fallback(leptos_axum::file_and_error_handler(shell))
.with_state(leptos_options);
@@ -30,10 +38,3 @@ async fn main() {
.await
.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
}