Rust宏扩展库dioxus-core-macro的使用:Dioxus框架核心宏处理器与组件化开发支持

Rust宏扩展库dioxus-core-macro的使用:Dioxus框架核心宏处理器与组件化开发支持

概述

dioxus-core-macro 提供了一些由 dioxus crate 使用的有用宏。这些包括:

  • rsx! 宏,支持模板和节点创建。
  • component 属性宏将函数表示为 Dioxus 组件。目前,这:
    • 将函数参数转换为自动派生的结构体。
    • 确保您的组件名称使用 PascalCase。
    • 未来可能还有更多功能。这个宏使我们能够区分函数和组件,这非常方便。
  • format_args_f 宏,允许使用 f-string 格式化并支持表达式。

安装

运行以下 Cargo 命令在您的项目目录中:

cargo add dioxus-core-macro

或者将以下行添加到您的 Cargo.toml:

dioxus-core-macro = "0.6.3"

示例

以下是一个使用 dioxus-core-macro 的完整示例:

use dioxus::prelude::*;

// 使用 component 属性宏定义一个组件
#[component]
fn MyComponent(name: String) -> Element {
    // 使用 rsx! 宏创建模板
    rsx! {
        div {
            h1 { "Hello, {name}!" }
            p { "This is a Dioxus component." }
        }
    }
}

// 主应用组件
#[component]
fn App() -> Element {
    rsx! {
        div {
            h1 { "Welcome to Dioxus" }
            MyComponent { name: "World".to_string() }
        }
    }
}

fn main() {
    // 启动应用
    launch(App);
}

完整示例代码

use dioxus::prelude::*;

// 定义一个简单的按钮组件
#[component]
fn CustomButton(text: String, on_click: EventHandler) -> Element {
    rsx! {
        button {
            // 绑定点击事件
            onclick: move |_| on_click.call(()),
            class: "btn btn-primary",
            // 显示按钮文本
            "{text}"
        }
    }
}

// 计数器状态组件
#[component]
fn Counter() -> Element {
    // 使用 use_state hook 管理状态
    let mut count = use_state(|| 0);
    
    rsx! {
        div {
            class: "counter-container",
            h2 { "当前计数: {count}" }
            
            // 增加按钮
            CustomButton {
                text: "增加".to_string(),
                on_click: move |_| count += 1
            }
            
            // 减少按钮
            CustomButton {
                text: "减少".to_string(),
                on_click: move |_| count -= 1
            }
            
            // 重置按钮
            CustomButton {
                text: "重置".to_string(),
                on_click: move |_| count.set(0)
            }
        }
    }
}

// 主应用组件
#[component]
fn App() -> Element {
    rsx! {
        div {
            class: "app",
            header {
                h1 { "Dioxus 计数器应用" }
                p { "使用 dioxus-core-macro 构建的示例应用" }
            }
            
            main {
                // 使用计数器组件
                Counter {}
            }
            
            footer {
                p { "基于 MIT 许可证开源" }
            }
        }
    }
}

fn main() {
    // 启动 Dioxus 应用
    launch(App);
}

贡献

  • 在我们的问题跟踪器上报告问题。
  • 加入 discord 并提问!

许可证

此项目根据 MIT 许可证授权。

除非您明确声明,否则任何有意提交包含在 Dioxus 中的贡献均应按照 MIT 许可证授权,无需任何附加条款或条件。


1 回复

Dioxus Core Macro:Rust宏扩展库的使用指南

介绍

dioxus-core-macro是Dioxus框架的核心宏处理器,专门为Rust语言设计,用于简化组件化开发。该库提供了一系列声明式宏,帮助开发者快速构建用户界面组件,同时保持Rust的类型安全和性能优势。

主要功能

  • 组件宏声明
  • 属性处理
  • JSX-like语法支持
  • 状态管理集成
  • 生命周期钩子处理

安装方法

在Cargo.tml中添加依赖:

[dependencies]
dioxus = "0.3"
dioxus-core-macro = "0.3"

基本使用方法

1. 定义组件

use dioxus::prelude::*;

#[component]
fn MyComponent(name: String) -> Element {
    rsx! {
        div {
            "Hello, {name}!"
        }
    }
}

2. 带状态的组件

#[component]
fn Counter() -> Element {
    let mut count = use_signal(|| 0);
    
    rsx! {
        div {
            h1 { "Count: {count}" }
            button {
                onclick: move |_| count += 1,
                "Increment"
            }
        }
    }
}

3. 属性处理

#[component]
fn Button(
    #[props(default = "primary")] variant: String,
    #[props(default = false)] disabled: bool,
    children: Element,
) -> Element {
    rsx! {
        button {
            class: "btn btn-{variant}",
            disabled: "{disabled}",
            {children}
        }
    }
}

高级用法

条件渲染

#[component]
fn ConditionalRender(show: bool) -> Element {
    rsx! {
        if show {
            div { "This is visible" }
        } else {
            div { "This is hidden" }
        }
    }
}

列表渲染

#[component]
fn TodoList(items: Vec<String>) -> Element {
    rsx! {
        ul {
            for item in items {
                li { key: "{item}", "{item}" }
            }
        }
    }
}

生命周期处理

#[component]
fn Timer() -> Element {
    let mut seconds = use_signal(|| 0);
    
    use_effect(move || {
        let mut interval = gloo_timers::callback::Interval::new(1000, move || {
            seconds += 1;
        });
        interval.forget();
    });
    
    rsx! { "Seconds: {seconds}" }
}

完整示例demo

// 完整示例:一个简单的待办事项应用
use dioxus::prelude::*;

fn main() {
    launch(App);
}

#[component]
fn App() -> Element {
    let mut todos = use_signal(|| vec![
        "学习Rust".to_string(),
        "学习Dioxus".to_string(),
        "构建Web应用".to_string()
    ]);
    let mut new_todo = use_signal(|| String::new());

    rsx! {
        div {
            class: "container",
            
            h1 { "待办事项列表" }
            
            // 添加新待办事项的表单
            form {
                onsubmit: move |event| {
                    event.stop_propagation();
                    if !new_todo().is_empty() {
                        todos.write().push(new_todo());
                        new_todo.set(String::new());
                    }
                },
                
                input {
                    r#type: "text",
                    placeholder: "输入新的待办事项...",
                    value: "{new_todo}",
                    oninput: move |event| new_todo.set(event.value())
                }
                button { r#type: "submit", "添加" }
            }
            
            // 待办事项列表
            TodoList { items: todos() }
            
            // 计数器组件示例
            Counter {}
        }
    }
}

#[component]
fn TodoList(items: Vec<String>) -> Element {
    rsx! {
        ul {
            class: "todo-list",
            
            for (index, item) in items.iter().enumerate() {
                li {
                    key: "{index}",
                    class: "todo-item",
                    
                    span { "{item}" }
                    button {
                        onclick: move |_| {
                            // 这里应该实现删除逻辑
                            println!("删除: {}", item);
                        },
                        "删除"
                    }
                }
            }
        }
    }
}

#[component]
fn Counter() -> Element {
    let mut count = use_signal(|| 0);
    
    rsx! {
        div {
            class: "counter",
            
            h2 { "计数器示例" }
            p { "当前计数: {count}" }
            
            button {
                onclick: move |_| count += 1,
                "增加"
            }
            button {
                onclick: move |_| count -= 1,
                "减少"
            }
            button {
                onclick: move |_| count.set(0),
                "重置"
            }
        }
    }
}

#[component]
fn Button(
    #[props(default = "primary")] variant: String,
    #[props(default = false)] disabled: bool,
    children: Element,
) -> Element {
    rsx! {
        button {
            class: "btn btn-{variant}",
            disabled: "{disabled}",
            {children}
        }
    }
}

注意事项

  1. 确保在组件函数上使用#[component]属性宏
  2. 组件必须返回Element类型
  3. 使用rsx!宏来声明UI结构
  4. 状态管理使用use_signal等hook函数

最佳实践

  • 保持组件小而专注
  • 合理使用props传递数据
  • 利用Rust的类型系统进行编译时检查
  • 使用key属性优化列表渲染性能

这个宏库极大地简化了Dioxus框架中的组件开发流程,让开发者能够以声明式的方式构建高性能的Web应用程序。

回到顶部