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();
}

关键特性

  1. 服务器端渲染(SSR):组件在服务器端渲染为HTML,提供更好的首屏性能和SEO支持
  2. 组件逻辑复用:通过#[server]宏标记的组件可以在多个地方复用
  3. 状态管理:支持组件内部状态管理,如示例中的计数器状态
  4. 高效渲染:使用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;
}

运行说明

  1. 启动服务器端:
cargo run --features ssr
  1. 启动客户端(在另一个终端):
cargo run

这个完整示例展示了:

  • 如何定义可SSR的组件
  • 服务器端渲染的实现
  • 客户端水合的过程
  • 同构组件的使用
  • 异步数据获取
  • 完整的项目结构配置

通过这个示例,您可以快速开始构建自己的Dioxus SSR应用。

回到顶部