Rust全栈Web开发框架Leptos与Actix集成库leptos_actix的使用:构建高性能响应式应用
// 使用leptos_actix集成库的完整示例
use actix_web::{web, App, HttpServer};
use leptos::*;
use leptos_actix::{generate_route_list, LeptosRoutes};
// 定义Leptos组件
#[component]
fn AppComponent(cx: Scope) -> impl IntoView {
let (count, set_count) = create_signal(cx, 0);
view! { cx,
<main>
<h1>"欢迎使用Leptos + Actix!"</h1>
<button
on:click=move |_| set_count.update(|n| *n += 1)
>
"点击计数: " {count}
</button>
</main>
}
}
// 配置Leptos选项
#[actix_web::main]
async fn main() -> std::io::Result<()> {
// 设置Leptos配置
let conf = get_configuration(None).await.unwrap();
let addr = conf.leptos_options.site_addr;
// 生成路由列表
let routes = generate_route_list(AppComponent);
println!("服务器运行在: http://{}", &addr);
HttpServer::new(move || {
let leptos_options = &conf.leptos_options;
let site_root = &leptos_options.site_root;
App::new()
// 提供Leptos路由
.leptos_routes(
leptos_options.to_owned(),
routes.to_owned(),
AppComponent,
)
// 提供静态文件服务
.service(actix_files::Files::new("/", site_root))
})
.bind(&addr)?
.run()
.await
}
// Cargo.toml依赖配置示例
/*
[package]
name = "leptos-actix-demo"
version = "0.1.0"
edition = "2021"
[dependencies]
leptos = { version = "0.5", features = ["csr"] }
leptos_actix = "0.8.5"
actix-web = "4.4"
actix-files = "0.6"
serde = { version = "1.0", features = ["derive"] }
[build-dependencies]
leptos = { version = "0.5", features = ["csr"] }
*/
这个示例展示了如何使用leptos_actix集成库将Leptos前端框架与Actix-web后端框架结合使用。主要包含:
- Leptos组件定义:创建了一个简单的计数器组件
- Actix服务器配置:设置HTTP服务器并集成Leptos路由
- 静态文件服务:提供前端资源文件服务
- 依赖配置:展示了所需的Cargo.toml依赖项
要运行此示例,需要按照内容中提供的安装命令添加leptos_actix依赖,并配置相应的构建选项。
完整示例代码:
// 完整可运行的leptos_actix集成示例
use actix_web::{web, App, HttpServer};
use leptos::*;
use leptos_actix::{generate_route_list, LeptosRoutes};
// 定义Leptos根组件
#[component]
fn AppComponent(cx: Scope) -> impl IntoView {
// 创建响应式信号用于计数器
let (count, set_count) = create_signal(cx, 0);
// 构建视图
view! { cx,
<main style="font-family: Arial, sans-serif; padding: 2rem;">
<h1>"欢迎使用Leptos + Actix集成示例"</h1>
<p>"这是一个完整的全栈Rust Web应用示例"</p>
<div style="margin: 2rem 0;">
<button
style="padding: 0.5rem 1rem; font-size: 1rem;"
on:click=move |_| set_count.update(|n| *n += 1)
>
"点击计数: " {count}
</button>
</div>
<div>
<p>"当前计数: " <strong>{count}</strong></p>
</div>
</main>
}
}
// 主函数 - Actix-web服务器入口点
#[actix_web::main]
async fn main() -> std::io::Result<()> {
// 获取Leptos配置
let conf = get_configuration(None).await.unwrap();
let addr = conf.leptos_options.site_addr;
// 生成应用路由列表
let routes = generate_route_list(AppComponent);
// 打印服务器启动信息
println!("🚀 服务器启动成功!");
println!("📡 访问地址: http://{}", &addr);
println!("🔄 Leptos路由已配置");
// 创建并配置HTTP服务器
HttpServer::new(move || {
let leptos_options = &conf.leptos_options;
let site_root = &leptos_options.site_root;
App::new()
// 集成Leptos路由处理
.leptos_routes(
leptos_options.to_owned(),
routes.to_owned(),
AppComponent,
)
// 提供静态文件服务(CSS、JS等)
.service(actix_files::Files::new("/", site_root))
// 默认路由处理
.default_service(web::route().to(leptos_actix::handle_server_fns))
})
.bind(&addr)?
.run()
.await
}
// 可选的错误处理页面组件
#[component]
fn ErrorPage(cx: Scope) -> impl IntoView {
view! { cx,
<div style="text-align: center; padding: 2rem;">
<h1>"页面未找到"</h1>
<p>"抱歉,您访问的页面不存在"</p>
</div>
}
}
对应的Cargo.toml配置文件:
[package]
name = "leptos-actix-demo"
version = "0.1.0"
edition = "2021"
[dependencies]
leptos = { version = "0.5", features = ["csr"] }
leptos_actix = "0.8.5"
actix-web = "4.4"
actix-files = "0.6"
serde = { version = "1.0", features = ["derive"] }
[build-dependencies]
leptos = { version = "0.5", features = ["csr"] }
构建和运行说明:
- 创建新的Rust项目:
cargo new leptos-actix-demo
- 将上述代码复制到src/main.rs
- 将Cargo.toml配置复制到项目根目录
- 运行项目:
cargo run
- 在浏览器中访问 http://localhost:3000
这个完整示例包含了基本的Leptos组件、Actix-web服务器配置、静态文件服务和错误处理,可以直接运行使用。
1 回复
Leptos与Actix集成库leptos_actix使用指南
概述
leptos_actix是一个将Leptos前端框架与Actix-web后端服务器无缝集成的库,让开发者能够构建高性能的响应式Web应用。它提供了服务端渲染(SSR)、API路由处理和前端组件渲染的统一解决方案。
核心特性
- 服务端渲染(SSR)支持
- 客户端hydration
- 统一的API路由处理
- 热重载开发体验
- 类型安全的端到端通信
安装配置
在Cargo.toml中添加依赖:
[dependencies]
leptos = "0.5"
leptos_actix = "0.2"
actix-web = "4.4"
基本使用示例
1. 定义Leptos组件
use leptos::*;
#[component]
pub fn App(cx: Scope) -> impl IntoView {
let (count, set_count) = create_signal(cx, 0);
view! { cx,
<main>
<h1>"Leptos + Actix计数器"</h1>
<button on:click=move |_| set_count.update(|n| *n += 1)>
"点击次数: " {count}
</button>
</main>
}
}
2. 配置Actix服务器
use actix_web::*;
use leptos_actix::{generate_route_list, LeptosRoutes};
use leptos::*;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let conf = get_configuration(None).unwrap();
let addr = conf.leptos_options.site_addr;
let routes = generate_route_list(|cx| view! { cx, <App/> });
HttpServer::new(move || {
let leptos_options = &conf.leptos_options;
let site_root = &leptos_options.site_root;
App::new()
.route("/api/{tail:.*}", leptos_actix::handle_server_fns())
.leptos_routes(leptos_options.to_owned(), routes.to_owned(), |cx| {
view! { cx, <App/> }
})
.service(fs::Files::new("/", site_root))
})
.bind(&addr)?
.run()
.await
}
3. 创建服务器函数
#[server(GetUserData, "/api")]
pub async fn get_user_data(user_id: i32) -> Result<String, ServerFnError> {
// 模拟数据库查询
Ok(format!("用户{}的数据", user_id))
}
#[component]
pub fn UserProfile(cx: Scope, user_id: i32) -> impl IntoView {
let user_data = create_resource(
cx,
move || user_id,
|id| async move { get_user_data(id).await }
);
view! { cx,
<div>
<h2>"用户信息"</h2>
<Suspense fallback=move || view! { cx, <p>"加载中..."</p> }>
{move || user_data.read().map(|data|
view! { cx, <p>{data.unwrap_or_else(|_| "加载失败".to_string())}</p> }
)}
</Suspense>
</div>
}
}
完整示例demo
基于上述示例,这里提供一个完整的leptos_actix集成项目示例:
Cargo.toml
[package]
name = "leptos-actix-demo"
version = "0.1.0"
edition = "2021"
[dependencies]
leptos = { version = "0.5", features = ["serde", "ssr"] }
leptos_actix = "0.2"
actix-web = "4.4"
serde = { version = "1.0", features = ["derive"] }
src/main.rs
use actix_web::*;
use leptos::*;
use leptos_actix::{generate_route_list, LeptosRoutes};
// 导入自定义组件
use leptos_actix_demo::App;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
// 获取Leptos配置
let conf = get_configuration(None).unwrap();
let addr = conf.leptos_options.site_addr;
// 生成路由列表
let routes = generate_route_list(|cx| view! { cx, <App/> });
println!("服务器运行在: http://{}", &addr);
HttpServer::new(move || {
let leptos_options = &conf.leptos_options;
let site_root = &leptos_options.site_root;
App::new()
// 注册API路由处理
.route("/api/{tail:.*}", leptos_actix::handle_server_fns())
// 注册Leptos路由
.leptos_routes(
leptos_options.to_owned(),
routes.to_owned(),
|cx| view! { cx, <App/> },
)
// 静态文件服务
.service(fs::Files::new("/", site_root))
})
.bind(&addr)?
.run()
.await
}
src/lib.rs
use leptos::*;
use serde::{Deserialize, Serialize};
// 主应用组件
#[component]
pub fn App(cx: Scope) -> impl IntoView {
let (count, set_count) = create_signal(cx, 0);
view! { cx,
<main style="font-family: Arial, sans-serif; padding: 20px;">
<h1>"Leptos + Actix 全栈示例"</h1>
<div>
<button
on:click=move |_| set_count.update(|n| *n += 1)
style="padding: 10px 20px; font-size: 16px;"
>
"点击次数: " {count}
</button>
</div>
<hr/>
<UserProfile user_id=1/>
</main>
}
}
// 服务器函数 - 获取用户数据
#[server(GetUserData, "/api")]
pub async fn get_user_data(user_id: i32) -> Result<String, ServerFnError> {
// 模拟数据库查询或API调用
tokio::time::sleep(std::time::Duration::from_secs(1)).await; // 模拟延迟
Ok(format!("用户ID {} 的详细信息: 姓名: 张三, 年龄: 25, 职业: 开发者", user_id))
}
// 用户资料组件
#[component]
pub fn UserProfile(cx: Scope, user_id: i32) -> impl IntoView {
let user_data = create_resource(
cx,
move || user_id,
|id| async move { get_user_data(id).await }
);
view! { cx,
<div style="margin-top: 20px;">
<h2>"用户信息"</h2>
<Suspense fallback=move || view! { cx,
<p style="color: #666;">"加载用户数据中..."</p>
}>
{move || user_data.read().map(|data|
match data {
Ok(data) => view! { cx,
<div style="background: #f5f5f5; padding: 15px; border-radius: 5px;">
<p>{data}</p>
</div>
},
Err(_) => view! { cx,
<p style="color: red;">"加载用户数据失败"</p>
}
}
)}
</Suspense>
</div>
}
}
项目结构建议
src/
├── main.rs # Actix服务器入口
├── lib.rs # Leptos组件和共享代码
├── app/
│ ├── mod.rs
│ └── components/ # 可复用组件
└── api/
├── mod.rs
└── handlers/ # API处理函数
开发命令
# 开发模式(带热重载)
cargo leptos watch
# 生产构建
cargo leptos build --release
# 运行生产服务器
cargo run --release
注意事项
- 确保在Cargo.toml中正确配置leptos特性标志
- 服务器函数必须标记为
async
并使用#[server]
宏 - 正确处理错误类型,使用
ServerFnError
作为返回类型 - 注意静态资源文件的路径配置
这个集成方案提供了完整的全栈开发体验,结合了Leptos的响应式前端和Actix的高性能后端优势。