You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Dioxus Router传递Channel实现组件间通信?

在Dioxus Router中通过共享状态传递Channel实现组件通信

你可以利用Dioxus的use_shared_state机制在App组件中创建Channel,将其传递给路由组件,避免全局静态状态带来的复杂度。以下是具体实现方案:

1. 定义消息类型与初始化共享Channel

先定义组件间传递的消息类型,在App组件中创建mpsc Channel并将Sender存入共享状态:

use dioxus::prelude::*;
use tokio::sync::mpsc;

// 根据业务需求定义组件间传递的消息
#[derive(Clone, Debug)]
pub enum AppMessage {
    UserLoggedIn(String),
    ChatMessage(String),
}

#[tokio::main]
async fn main() {
    dioxus_desktop::launch(App);
}

fn App(cx: Scope) -> Element {
    // 创建带缓冲区的mpsc Channel
    let (sender, mut receiver) = mpsc::channel::<AppMessage>(100);
    
    // 将Sender存入共享状态,供所有子组件获取
    use_shared_state_provider(cx, || sender);
    
    // 在App组件中监听Channel消息,做全局处理
    let messages = use_shared_state_provider(cx, || Vec::<String>::new());
    cx.spawn(async move {
        let messages = messages.clone();
        while let Some(msg) = receiver.recv().await {
            match msg {
                AppMessage::UserLoggedIn(name) => {
                    println!("用户登录: {}", name);
                }
                AppMessage::ChatMessage(content) => {
                    messages.write().push(content);
                }
            }
        }
    });

    render! {
        style { include_str!("./style.css") },
        Router::<Route> {},
    }
}

#[derive(Clone, Routable, Debug, PartialEq)]
pub enum Route {
    #[route("/")]
    Login {},

    #[route("/chat")]
    Chat {
        name: String,
    },
}

2. 在Login组件中使用Sender发送消息并跳转路由

Login组件获取共享的Sender,发送登录消息后跳转到Chat页面:

fn Login(cx: Scope) -> Element {
    let sender = use_shared_state::<mpsc::Sender<AppMessage>>(cx).unwrap();
    let username = use_state(cx, String::new);

    render! {
        div {
            input {
                value: "{username}",
                oninput: move |evt| username.set(evt.value.clone()),
                placeholder: "输入用户名"
            }
            button {
                onclick: move |_| {
                    let name = username.clone();
                    cx.spawn(async move {
                        // 发送登录消息到全局Channel
                        sender.send(AppMessage::UserLoggedIn(name.get().clone())).await.unwrap();
                        // 跳转到Chat页面
                        cx.navigate_to(format!("/chat?name={}", name.get()));
                    });
                },
                "登录"
            }
        }
    }
}

3. 在Chat组件中发送消息并接收全局消息列表

Chat组件获取Sender发送聊天消息,同时读取共享的消息列表展示:

fn Chat(cx: Scope, name: String) -> Element {
    let sender = use_shared_state::<mpsc::Sender<AppMessage>>(cx).unwrap();
    let messages = use_shared_state::<Vec<String>>(cx).unwrap();
    let input_msg = use_state(cx, String::new);

    render! {
        div {
            h1 { "欢迎, {name}!" }
            input {
                value: "{input_msg}",
                oninput: move |evt| input_msg.set(evt.value.clone()),
                placeholder: "输入消息"
            }
            button {
                onclick: move |_| {
                    let msg = input_msg.clone();
                    cx.spawn(async move {
                        sender.send(AppMessage::ChatMessage(msg.get().clone())).await.unwrap();
                        msg.set(String::new());
                    });
                },
                "发送"
            }
            div {
                h3 { "消息列表:" }
                for msg in messages.read().iter() {
                    p { "{msg}" }
                }
            }
        }
    }
}

方案优势

  • 基于Dioxus原生共享状态机制,无需引入复杂的全局状态管理器
  • Channel的Sender支持克隆,子组件可安全获取并发送消息
  • 全局消息监听集中在App组件,便于统一处理日志、状态更新等逻辑

内容的提问来源于stack exchange,提问作者lucianopinochet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 09:27:49