Rust Web框架Dioxus服务器端宏库dioxus_server_macro的使用,实现高效服务端渲染与组件逻辑复用
Rust Web框架Dioxus服务器端宏库dioxus_server_macro的使用,实现高效服务端渲染与组件逻辑复用
安装
在项目目录中运行以下Cargo命令:
cargo add dioxus_server_macro
或者在Cargo.toml中添加以下行:
dioxus_server_macro = "0.6.2"
使用示例
下面是一个完整的服务器端渲染(SSR)示例,展示了如何使用dioxus_server_macro
实现组件逻辑复用:
use dioxus::prelude::*;
use dioxus_server_macro::server;
// 定义一个可复用的服务器端组件
#[server]
fn Counter(cx: Scope) -> Element {
let mut count = use_state(cx, || 0);
cx.render(rsx! {
div {
h1 { "Count: {count}" }
button { onclick: move |_| count += 1, "Increment" }
button { onclick: move |_| count -= 1, "Decrement" }
}
})
}
// 主应用组件
#[server]
fn App(cx: Scope) -> Element {
cx.render(rsx! {
div {
h1 { "Dioxus Server-Side Rendering Example" }
Counter {}
Counter {}
}
})
}
// 服务器入口点
#[tokio::main]
async fn main() {
// 创建Dioxus应用配置
let config = dioxus::server::Config::new()
.with_addr("127.0.0.1:8080")
.with_app(App);
// 启动服务器
dioxus::server::launch(config).await.unwrap();
}
关键特性
- 服务器端渲染(SSR):组件在服务器端渲染为HTML,提供更好的首屏性能和SEO支持
- 组件逻辑复用:通过
#[server]
宏标记的组件可以在多个地方复用 - 状态管理:支持组件内部状态管理,如示例中的计数器状态
- 高效渲染:使用Dioxus的虚拟DOM diff算法进行高效更新
完整示例demo
下面是一个更完整的服务器端渲染应用示例,包含了多个组件和路由功能:
use dioxus::prelude::*;
use dioxus_server_macro::server;
// 可复用的导航栏组件
#[server]
fn NavBar(cx: Scope) -> Element {
cx.render(rsx! {
nav {
ul {
li { a { href: "/", "Home" } }
li { a { href: "/about", "About" } }
li { a { href: "/counter", "Counter Demo" } }
}
}
})
}
// 首页组件
#[server]
fn Home(cx: Scope) -> Element {
cx.render(rsx! {
div {
NavBar {}
h1 { "Welcome to Dioxus SSR Demo" }
p { "This is a server-side rendered application" }
}
})
}
// 关于页面组件
#[server]
fn About(cx: Scope) -> Element {
cx.render(rsx! {
div {
NavBar {}
h1 { "About Page" }
p { "This is the about page content" }
}
})
}
// 计数器页面组件
#[server]
fn CounterPage(cx: Scope) -> Element {
cx.render(rsx! {
div {
NavBar {}
Counter {}
}
})
}
// 主路由组件
#[server]
fn App(cx: Scope) -> Element {
// 使用Dioxus的路由功能
let route = use_route(cx);
cx.render(match route.segment(0).unwrap_or("") {
"about" => rsx! { About {} },
"counter" => rsx! { CounterPage {} },
_ => rsx! { Home {} },
})
}
// 服务器入口点
#[tokio::main]
async fn main() {
// 创建Dioxus应用配置
let config = dioxus::server::Config::new()
.with_addr("127.0.0.1:8080")
.with_app(App);
// 启动服务器
dioxus::server::launch(config).await.unwrap();
}
项目信息
- 版本: 0.6.2
- 许可证: MIT OR Apache-2.0
- 大小: 3.46 KiB
- 所有者: Jonathan Kelley
1 回复
Dioxus服务器端宏库dioxus_server_macro使用指南
概述
dioxus_server_macro
是Dioxus Web框架的服务器端宏库,主要用于实现高效的服务端渲染(SSR)和组件逻辑复用。它允许开发者编写一次组件代码,同时在客户端和服务器端运行,大大提高了开发效率。
主要特性
- 服务端渲染支持:在服务器端预渲染组件,加快页面加载速度
- 同构组件:同一组件可在客户端和服务器端复用
- 高效渲染:优化的渲染管道减少不必要的DOM操作
- 宏简化:通过过程宏简化SSR相关代码编写
安装
在Cargo.toml中添加依赖:
[dependencies]
dioxus = { version = "0.4", features = ["ssr"] }
dioxus-server-macro = "0.4"
完整示例代码
下面是一个完整的Dioxus SSR应用示例,包含服务器端和客户端代码:
1. 项目结构
my-dioxus-app/
├── Cargo.toml
├── src/
│ ├── main.rs # 客户端入口
│ └── server.rs # 服务器端代码
2. Cargo.toml 配置
[package]
name = "my-dioxus-app"
version = "0.1.0"
edition = "2021"
[dependencies]
dioxus = { version = "0.4", features = ["ssr"] }
dioxus-server-macro = "0.4"
tokio = { version = "1.0", features = ["full"] }
axum = "0.6"
3. 共享组件 (src/lib.rs)
use dioxus::prelude::*;
use dioxus_server_macro::*;
// 可SSR的问候组件
#[server_component]
pub fn Greeting(name: String) -> Element {
rsx! {
h1 { style: "color: blue;", "Hello, {name}!" }
p { "This component works on both server and client!" }
}
}
// 数据获取组件
#[server_component]
pub async fn UserProfile(user_id: u32) -> Element {
// 模拟异步数据获取
let user_name = format!("User {}", user_id);
rsx! {
div {
h2 { "User Profile" }
p { "ID: {user_id}" }
p { "Name: {user_name}" }
}
}
}
4. 服务器端代码 (src/server.rs)
use dioxus::prelude::*;
use axum::{Router, routing::get, response::Html};
// 渲染整个页面
#[server_fn]
async fn render_page() -> String {
let mut app = VirtualDom::new(|| {
rsx! {
doctype!("html")
html {
head {
title { "Dioxus SSR Example" }
}
body {
Greeting { name: "Server Side".to_string() }
UserProfile { user_id: 42 }
}
}
}
});
let _ = app.rebuild();
dioxus_ssr::render(&app)
}
// 设置Axum路由
pub async fn start_server() {
let app = Router::new()
.route("/", get(|| async { Html(render_page().await) }));
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
5. 客户端代码 (src/main.rs)
use dioxus::prelude::*;
use dioxus_web::Config;
fn App() -> Element {
rsx! {
div {
Greeting { name: "Client Side".to_string() }
UserProfile { user_id: 123 }
}
}
}
fn main() {
dioxus_web::launch_cfg(App, Config::new().hydrate(true));
}
6. 主入口 (src/main.rs 完整版)
mod server;
#[cfg(not(feature = "ssr"))]
fn main() {
// 客户端执行
use dioxus::prelude::*;
use dioxus_web::Config;
fn App() -> Element {
rsx! {
div {
h1 { "Client Side Application" }
crate::Greeting { name: "Client".to_string() }
crate::UserProfile { user_id: 1 }
}
}
}
dioxus_web::launch_cfg(App, Config::new().hydrate(true));
}
#[cfg(feature = "ssr")]
#[tokio::main]
async fn main() {
// 服务器端执行
server::start_server().await;
}
运行说明
- 启动服务器端:
cargo run --features ssr
- 启动客户端(在另一个终端):
cargo run
这个完整示例展示了:
- 如何定义可SSR的组件
- 服务器端渲染的实现
- 客户端水合的过程
- 同构组件的使用
- 异步数据获取
- 完整的项目结构配置
通过这个示例,您可以快速开始构建自己的Dioxus SSR应用。