Rust Dioxus 桌面框架详细使用说明

定位:Dioxus 是组件 + RSX + 信号的全 Rust 跨端 UI 框架——用 React 的心智(组件 / Props / Hooks),但状态用信号、更新靠订阅(细粒度、非虚拟 DOM 全树 diff)。一份代码目标 Web / 桌面 / 移动 / 全栈
诚实前提Dioxus 桌面今天 = 系统 WebView(wry/tao,与 Tauri 同底座),并非 iced/egui 那样的自绘;差异在「UI 全用 Rust RSX 写」而非 JS/HTML。自研的 Blitz/Dioxus Native(WGPU 直渲 HTML/CSS)是未来方向、仍属实验。
版本基线(2026-09):Dioxus 0.7.x(dioxus-desktop 0.7.x)。0.7 带来 Subsecond 热补丁(连 Rust 逻辑都能热替换)。框架年轻、迭代极快,版本间破坏性变更偏多
一句话取舍:给「前端背景、想 all-in Rust、能接受追新」的团队;桌面渲染现状与 Tauri 无本质区别,选它多半是为了「全 Rust + 一份代码多端」。
:8 张内嵌 base64 SVG。所有易变 API 处均标注「以 docs.rs 对应版本为准」。

姊妹篇:docs/20260920_Rust-iced桌面框架使用说明.md(Elm 保留模式·自绘)、docs/20260920_Rust-egui桌面框架使用说明.md(立即模式·自绘)、docs/20260920_Rust桌面GUI框架横评.md(五框架横评)。


目录

  1. 一、Dioxus 是什么:组件 + RSX + 信号
  2. 二、安装与第一个程序
  3. 三、RSX:用 Rust 写 JSX
  4. 四、组件与 Props
  5. 五、信号 Signals:细粒度响应式
  6. 六、事件与受控输入
  7. 七、派生与共享:use_memo · use_effect · use_context
  8. 八、异步:use_resource
  9. 九、桌面 = 系统 WebView:与 Tauri 同底座
  10. 十、中文与 WebView:省心处与真正的坑
  11. 十一、样式与资源:CSS · asset! · 双主题
  12. 十二、一份代码多端:Web/桌面/移动/全栈
  13. 十三、完整实例:待办事项 Todo
  14. 十四、常见坑速查
  15. 十五、与 CMX 工作区的呼应
  16. 十六、版本与参考资源

一、Dioxus 是什么:组件 + RSX + 信号

图1:Dioxus 三支柱(组件+RSX+信号)

Dioxus 只有三个核心概念,凑齐就懂大半:

  • 组件 Component:一个返回 Element 的普通函数(fn App() -> Element)。可带 Props、可嵌套组合成组件树——就是 React 组件的心智。
  • RSX:声明 UI 的宏(rsx! { … }),写法接近 JSX,但是编译期宏、有类型检查,不是字符串模板。
  • 信号 Signal:响应式状态(use_signal(|| 0))。读它就订阅它,改它就通知订阅者——只重新渲染读了这个信号的组件,天然细粒度。

与 React 的最大不同:React 靠虚拟 DOM 全树 diff 找变化;Dioxus 靠信号订阅精确定位——改一个信号,框架直接知道该更新哪几处,不用比对整棵树。心智像 React,机制更省。

与本系列另外两位的不同:iced 是 Elm 保留模式、egui 是立即模式,两者都自绘;Dioxus 是组件/信号,且桌面走 WebView(第 9 节详解)。三种世界观各有主场。

二、安装与第一个程序

Cargo.toml——桌面目标开 desktop feature:

[dependencies]
dioxus = { version = "0.7", features = ["desktop"] }
# 换目标只改 feature:web / mobile / fullstack

# 推荐装 CLI(热重载/多端构建):cargo binstall dioxus-cli  → 命令是 dx

src/main.rs——最小计数器,全文如下

use dioxus::prelude::*;

fn main() {
    dioxus::launch(App);        // 启动一个组件
}

// 组件 = 返回 Element 的函数(约定用大驼峰命名,rsx 才认它是组件)
fn App() -> Element {
    // 信号:响应式状态。要改就加 mut
    let mut count = use_signal(|| 0);

    rsx! {
        h1 { "计数: {count}" }                        // 读 count → 订阅;count 变这里自动更新
        button { onclick: move |_| count += 1, "加一" }
        button { onclick: move |_| count -= 1, "减一" }
    }
}

dx serve 跑起来(带热重载),或 cargo run。对比 iced 的四件套、egui 的每帧 update,Dioxus 这里是组件 + 信号:状态是 use_signal,界面是 rsx!,点击直接 count += 1 改信号,读了它的地方自动刷新。

好消息:因为桌面是 WebView,中文默认就能显示(系统浏览器引擎提供字体),没有 iced/egui 那种「先装中文字体」的坑(第 10 节展开这个反转)。

三、RSX:用 Rust 写 JSX

图2:RSX 解剖

rsx! 是声明 UI 的宏,长得像 JSX/HTML,但是编译期宏、带 Rust 类型检查。要素:

rsx! {
    // 元素:名字 + 花括号;属性写 key: value,子节点直接嵌套
    div {
        class: "card",
        id: "main",

        // 文本 + 插值:{signal} / {表达式} 直接插进字符串
        h1 { "计数: {count}" }
        p { "两倍是 {count() * 2}" }

        // 事件:on 开头,值是闭包
        button {
            onclick: move |_| count += 1,
            "加一"                                // 子节点也可以是纯文本
        }

        // 循环:for 直接写在 rsx 里;列表项给稳定的 key
        for todo in todos.read().iter() {
            li { key: "{todo.id}", "{todo.text}" }
        }

        // 条件:if / else 也直接内联
        if count() > 5 {
            p { class: "warn", "有点多了!" }
        }
    }
}
语法说明
div { … }元素;小写=HTML 元素,大写=组件(MyComp { … }
class: "x", onclick: …属性 / 事件,写成 key: value
"文本 {signal}"文本子节点 + 插值({} 里可放信号或表达式)
for x in it { … }列表渲染;每项建议给 key
if cond { … } else { … }条件渲染
{ 表达式 }内联任意返回 Element 的 Rust 表达式

rsx! 全程走 Rust 类型系统:属性名拼错、信号类型不对,编译期就报错——这是它比「字符串模板」强的地方。dx serve 下改 rsx 还能热重载即时看到。

四、组件与 Props

组件就是返回 Element 的函数。要接收参数(Props),用 #[component] 宏把函数参数变成属性:

use dioxus::prelude::*;

// 用 #[component]:函数参数即 Props
#[component]
fn Greeting(name: String, count: i32) -> Element {
    rsx! { p { "你好 {name},这是第 {count} 次" } }
}

// 父组件里像写 HTML 标签一样用它(大驼峰名)
fn App() -> Element {
    rsx! {
        Greeting { name: "张三".to_string(), count: 1 }
        Greeting { name: "李四".to_string(), count: 2 }
    }
}

// 需要更多控制(默认值/可选)时,手写 Props 结构体:
#[derive(Props, PartialEq, Clone)]
struct CardProps {
    title: String,
    #[props(default = false)]     // 可选属性带默认值
    highlighted: bool,
    children: Element,            // 接收子节点(类似 slot)
}

#[component]
fn Card(props: CardProps) -> Element {
    rsx! {
        div { class: if props.highlighted { "card hot" } else { "card" },
            h3 { "{props.title}" }
            {props.children}                        // 渲染传进来的子节点
        }
    }
}

要点:

  • 组件名用大驼峰Greeting),rsx! 靠大小写区分「组件」与「HTML 元素」。
  • children: Element 让组件接收子节点(Card { Foo {} } 里的 Foo {}),类似插槽。
  • Props 需要 PartialEq:Dioxus 靠它判断属性变没变、要不要重渲子组件。

五、信号 Signals:细粒度响应式

图3:信号细粒度响应式

信号是 Dioxus 状态管理的核心。三件事记牢:读=订阅、改=通知、Copy=随便传

let mut count = use_signal(|| 0);

// —— 读 ——(在组件/rsx 里读 = 订阅它,之后它变你就重渲)
let now = count();          // 调用语法,最常用
let now = *count.read();    // 显式读

// —— 改 ——
count += 1;                 // 运算符
count.set(10);              // 直接设
count.write().push(x);      // 拿可变引用改内部(如 Vec/结构体)
*count.write() += 1;        // 显式写

// —— Copy ——:信号是 Copy,可直接传给子组件、丢进闭包/async,无需 clone
let doubled = use_memo(move || count() * 2);   // 派生信号
spawn(async move { count += 1; });             // 异步里也能用

细粒度响应式是它的精髓:

  • 订阅发生在「读」处:某组件读了 countcount 变时只有它(及其它读者)重跑;没读的组件纹丝不动。
  • 因此没有虚拟 DOM 全树 diff——框架直接知道该更新谁。大列表、深层树里这很省。
  • 只读场景给子组件传 ReadSignal<T>(只读信号),读写场景传 Signal<T>

对比:iced 每次 view 重建整棵界面描述;egui 每帧重跑整个 UI;Dioxus 只重跑「读了变化信号」的组件——三者更新粒度递减,Dioxus 这点最接近 React 但更精确。

六、事件与受控输入

事件处理器是 on* 属性 + 闭包;受控输入把信号和输入框双向绑起来:

let mut name = use_signal(String::new);

rsx! {
    input {
        value: "{name}",                        // 信号 → 输入框(受控)
        oninput: move |e| name.set(e.value()),  // 输入框 → 信号
        onkeydown: move |e| {
            if e.key() == Key::Enter { /* 提交 */ }
        },
    }
    p { "你好, {name}" }                          // name 一变,这里自动更新

    // 常见事件:onclick / ondoubleclick / onmouseenter / onchange / onsubmit …
    button {
        onclick: move |e| {
            e.stop_propagation();                // 事件对象有 DOM 那套方法
            name.set(String::new());
        },
        "清空"
    }
}
事件取值
oninput / onchangee.value() 拿输入内容
onclick / onmouse*e.stop_propagation() / 坐标等
onkeydown / onkeyupe.key()Key::Enter 等)
onsubmit表单提交(配 prevent_default

因为渲染层是 WebView,事件对象就是浏览器那套语义value()/key()/stop_propagation()…),前端经验可直接迁移。

七、派生与共享:use_memo · use_effect · use_context

除了 use_signal,常用 Hook 还有派生、副作用、跨组件共享:

// use_memo:派生值,依赖(这里是 count)变了才重算,结果本身也是信号
let doubled = use_memo(move || count() * 2);

// use_effect:副作用,依赖自动追踪;读了谁、谁变就重跑
use_effect(move || {
    println!("count 变成了 {}", count());       // 日志/订阅外部/同步 DOM 等
});

// use_context_provider / use_context:跨层级共享状态,免 prop drilling
#[derive(Clone, Copy)]
struct Theme(Signal<bool>);                     // 建议用 newtype 包一层(按类型取)

fn App() -> Element {
    use_context_provider(|| Theme(Signal::new(false)));  // 父:提供
    rsx! { Child {} }
}

fn Child() -> Element {
    let theme = use_context::<Theme>();          // 子:任意深度取用
    rsx! { p { "暗色模式: {theme.0}" } }
}
Hook用途
use_signal响应式状态(最常用)
use_memo派生值(依赖变才重算)
use_effect副作用(依赖自动追踪)
use_resource异步数据(第 8 节)
use_context_provider / use_context跨组件共享,免逐层传参
use_future / spawn起一个后台异步任务

Context 按类型(TypeId)索引,所以要存多个同底类型(如多个 String),各用一个 newtype 包起来区分。

八、异步:use_resource

图4:use_resource 异步生命周期

异步拉数据用 use_resource:组件里发起,任务后台跑,结果一到自动重渲——读它就订阅它。

fn UserCard() -> Element {
    // 发起异步任务;返回一个 Resource,读它会订阅
    let mut user = use_resource(move || async move {
        reqwest::get("https://api.example.com/user")
            .await?
            .text()
            .await
    });

    rsx! {
        // 读 resource:None=还在跑,Some(Ok)=成功,Some(Err)=失败
        match &*user.read() {
            Some(Ok(text)) => rsx! { p { "用户:{text}" } },
            Some(Err(e))   => rsx! { p { class: "err", "出错:{e}" } },
            None           => rsx! { p { "加载中…" } },
        }
        button { onclick: move |_| user.restart(), "刷新" }   // 手动重跑
    }
}

要点:

  • use_resource(|| async { … }) 首帧立即返回(值为 None),任务在后台异步跑,完成后自动触发重渲。
  • 读到的是 Option<Result<T, E>>None 加载中、Some(Ok) 成功、Some(Err) 失败。
  • 依赖自动追踪:闭包里读了别的信号,那个信号变时 resource 会自动重跑;也可手动 .restart()
  • 全栈项目里,把这里的 reqwest::get 换成 #[server] 服务端函数即可前后端同源(第 12 节)。

match 内联在 rsx 里的写法随版本略有差异,个别版本更推荐 if let 或把分支抽成函数——以你锁定版本的 docs.rs / 指南为准。

九、桌面 = 系统 WebView:与 Tauri 同底座

图5:桌面 = 系统 WebView

这是选型前必须看清的一节:Dioxus 桌面今天的渲染 = 系统 WebView,与 Tauri 同底座(wry/tao)。

  • 你的 RSX/组件在 Rust 侧跑,维护一棵 VirtualDom,信号驱动精确 diff;变更喂给 dioxus-desktopwry/tao系统 WebView(Windows 的 WebView2 / macOS 的 WKWebView / Linux 的 WebKitGTK)渲染。
  • 与 Tauri 的真正区别不在渲染,而在「UI 用什么写」:Dioxus 用 Rust RSX,Tauri 用任意 Web 前端(React/Vue/Svelte,或 Leptos/Yew)。二者甚至可组合——Dioxus 可以当 Tauri 的前端
  • 自绘是未来、非现在:Dioxus 押注的 Blitz/Dioxus Native(用 WGPU 直渲 HTML/CSS、Taffy 布局)成熟后才能摆脱三平台 WebView 差异,但目前仍是实验品。
  • Web 目标则没有 WebView 中间层:同一份组件编到 WASM 直接跑浏览器。

一句诚实话:如果你冲着「像 iced/egui 那样的纯自绘、像素级跨平台一致」来,Dioxus 桌面今天给不了——它给的是「全 Rust 写 UI + 一份代码多端 + WebView 渲染」。想清楚要的是哪一个。

十、中文与 WebView:省心处与真正的坑

iced/egui 那节讲「怎么装中文字体」,到 Dioxus 这里反转了——因为渲染是 WebView:

省心的地方(WebView 白送)

  • 中文默认就显示:系统浏览器引擎自带完整字体栈,"中文" 直接正常,无需 set_fonts / 打包字体
  • 输入法(IME)成熟:候选框、预编辑全由系统 WebView 处理,中文输入体验最省心。
  • 复杂排版最强:换行、竖排、RTL、emoji——浏览器级排版能力全都有。
  • CSS 生态全量复用:Flexbox/Grid、动画、任意 CSS 框架照单全收。

真正的坑(转移到 WebView 跨平台差异)

说明
三平台内核不同WebView2 / WKWebView / WebKitGTK,CSS/JS 行为有差异
Linux 是重灾区WebKitGTK 兼容性/依赖是常见坑位,要留测试预算
包体依赖系统 WebView包很小(不带引擎),但 Windows 老系统需分发 WebView2 Runtime
性能上限受 WebView 制约虽无 JS 桥(UI 逻辑是 Rust),渲染仍是 WebView 天花板

一句话:Dioxus 把 iced/egui 的「字体坑」换成了「WebView 跨平台一致性坑」。中文/IME/排版省心了,但三平台 WebView 内核差异要专门测——这和 Tauri 是同一类烦恼。

十一、样式与资源:CSS · asset! · 双主题

图6:样式与资源

Dioxus 的样式就是 CSS(因为渲染是 WebView)。静态资源用 asset! 登记、Stylesheet 注入:

use dioxus::prelude::*;

// asset!:编译期登记资源,产出带哈希的路径(自动进产物)
static MAIN_CSS: Asset = asset!("/assets/main.css");

fn App() -> Element {
    rsx! {
        document::Stylesheet { href: MAIN_CSS }     // 注入全局样式表

        // 主题:完全走 CSS 那套
        div {
            class: "card",                          // 类名切换
            style: "padding: 16px",                 // 内联样式
            "内容"
        }
    }
}

主题切换有多种 Web 惯用法,任选:

  • class 切换div { class: "{theme}" },配一套 .dark { … } CSS。
  • CSS 变量color: var(--accent),切主题只改根变量。
  • 媒体查询@media (prefers-color-scheme: dark) 跟随系统。
  • 也能直接上 Tailwind / 任意 CSS 框架

对齐 CMX 硬约束 #4(双主题通路、禁硬编码色值):因为桌面就是 WebView,CMX 现有的 --sap* 变量、data-cmx-skin / data-cmx-skin-tone 切肤那一整套可原样复用(和给 Tauri 做前端时一模一样)——这也是 Dioxus 相对 iced/egui 在「双主题合规」上的天然便利:不用像自绘框架那样从 palette 手动派生,直接用你已有的 CSS 主题体系。

十二、一份代码多端:Web/桌面/移动/全栈

图7:一份代码多端

Dioxus 的招牌是一份组件代码、多端目标——切目标基本只改 dx serve --platform

dx serve                       # 默认平台(按 Cargo.toml feature)
dx serve --platform desktop    # 桌面(WebView)
dx serve --platform web        # 网页(WASM)
dx serve --platform android    # 安卓模拟器/真机
dx build --release --platform desktop   # 出包
目标渲染 / 形态成熟度
Web编到 WASM,浏览器直接跑一级
桌面系统 WebView(wry/tao)官方支持(本文重点)
移动iOS / Android官方支持,生态较年轻
全栈#[server] 服务端函数(Axum 底座)一级

全栈的 #[server]前后端写在同一个 crate、同源调用:

// 这个函数只在服务端执行;客户端「像调普通 async 函数」一样调用它
#[server]
async fn save_todo(text: String) -> Result<(), ServerFnError> {
    // 只有服务端能碰 DB / 密钥
    db::insert(&text).await?;
    Ok(())
}

// 组件里(客户端)直接 await 它,框架负责生成 RPC
fn AddButton(text: String) -> Element {
    rsx! {
        button {
            onclick: move |_| {
                let text = text.clone();
                async move { let _ = save_todo(text).await; }
            },
            "保存到服务器"
        }
    }
}

这套 server functions 与 CMX 后端天然同族——Dioxus 全栈的底座就是 Axum,和 CMX 各引擎(axum)是一门技术。这也是它值得放进 CMX 观察名单的主要理由(第 15 节)。

十三、完整实例:待办事项 Todo

图8:Todo 应用界面

把前面的概念串起来——一个可编译的待办事项应用:

use dioxus::prelude::*;

fn main() {
    dioxus::launch(App);
}

#[derive(Clone, PartialEq)]
struct Todo {
    id: u64,
    text: String,
    done: bool,
}

// 信号是 Copy,可原样传进普通函数(这样两个事件处理器能复用同一段逻辑)
fn add_todo(mut input: Signal<String>, mut items: Signal<Vec<Todo>>, mut next_id: Signal<u64>) {
    let text = input().trim().to_string();
    if !text.is_empty() {
        items.write().push(Todo { id: next_id(), text, done: false });
        next_id.set(next_id() + 1);
        input.set(String::new());
    }
}

fn App() -> Element {
    let input = use_signal(String::new);
    let items = use_signal(Vec::<Todo>::new);
    let next_id = use_signal(|| 0u64);

    rsx! {
        h1 { "待办事项" }

        div {
            input {
                value: "{input}",
                oninput: move |e| input.clone().set(e.value()),
                onkeydown: move |e| if e.key() == Key::Enter { add_todo(input, items, next_id); },
            }
            button { onclick: move |_| add_todo(input, items, next_id), "添加" }
        }

        ul {
            for item in items.read().iter() {
                li { key: "{item.id}",
                    input {
                        r#type: "checkbox",
                        checked: item.done,
                        // item.id 是 Copy,被闭包按值捕获;items 是 Copy 信号
                        onchange: move |_| {
                            let mut items = items;
                            if let Some(t) = items.write().iter_mut().find(|t| t.id == item.id) {
                                t.done = !t.done;
                            }
                        },
                    }
                    span { "{item.text}" }
                    button {
                        onclick: move |_| { let mut items = items; items.write().retain(|t| t.id != item.id); },
                        "删除"
                    }
                }
            }
        }

        p { "共 {items().len()} 项 · 已完成 {items().iter().filter(|t| t.done).count()}" }
    }
}

这段覆盖了:信号状态、oninput 受控输入、回车提交、for 列表 + key、闭包按值捕获 Copy 信号、items.write() 改集合——就是图 8 那个界面。想接后端?把新增/删除换成 #[server] 函数即可(第 12 节)。中文无需额外处理(WebView 自带,第 10 节)。

十四、常见坑速查

症状正解
组件名用小写rsx 把它当 HTML 元素,渲染不出来组件一律大驼峰(MyComp
改了信号界面不动那个组件根本没「读」它订阅在读处;确保渲染里读了该信号
列表少写 key增删时错位/状态串味for 项给稳定 key: "{id}"
闭包里 clone 报错/繁琐以为信号要 clone信号是 Copy,直接传/捕获即可
Props 没 PartialEq编译报错或无法判断重渲Props #[derive(Props, PartialEq, Clone)]
Linux 跑不起来/白屏缺 WebKitGTK 依赖装系统 WebKitGTK 开发库;留跨平台测试
以为是自绘、追求像素一致三平台观感有差异桌面=WebView,与 Tauri 同类;差异要测
照抄旧教程编译不过0.4/0.5 API 差异大认准 0.7 的 docs.rs / 指南,别跨版本抄
dx 命令找不到没装 CLIcargo binstall dioxus-cli(命令是 dx

十五、与 CMX 工作区的呼应

对照本工作区(元数据驱动企业平台,前端以 Web 资产为主):

  1. Dioxus 值得放进观察名单,但当下非首选。横评(docs/20260920_Rust桌面GUI框架横评.md)结论:面向最终用户的桌面产品首选 Tauri 2(直接复用 frontend/ 的 UI5/Tabler 与双主题资产);Dioxus 桌面今天 = WebView,与 Tauri 相比无渲染优势,选它主要为「UI 也全用 Rust 写」。
  2. 它的独特价值 = 全栈同族#[server] 服务端函数的底座是 Axum,与 CMX 各引擎(axum)是一门技术。若未来希望「门户小工具类页面」也统一成 Rust、且前后端同源,Dioxus 全栈是顺理成章的路径。
  3. 双主题零成本对齐:因为是 WebView,CMX 的 --sap* 变量 + data-cmx-skin 切肤体系可原样复用,天然满足硬约束 #4(第 11 节)——这点与给 Tauri 做前端完全一致。
  4. 中文/IME 省心:WebView 自带,无自绘框架的字体坑(第 10 节)。
  5. 组合而非二选一:Dioxus 甚至可作为 Tauri 的前端(全 Rust RSX + Tauri 的插件/打包/安全模型),这是很多团队的实际用法。

与本系列的分工:iced=架构可演进的自绘桌面产品;egui=最快出活的内部工具/诊断面板;Dioxus=前端背景、想全 Rust 一份代码多端(桌面走 WebView)。三者主场不同,Dioxus 在 CMX 语境下更多是「未来若要 Rust 全栈前端」的候选。

十六、版本与参考资源

版本基线(2026-09):Dioxus 0.7.x。亮点是 Subsecond 热补丁(连 Rust 逻辑都能热替换,不只前端资源)。Dioxus 迭代极快、破坏性变更也最多(0.4→0.5→0.6→0.7 每次 API 都有明显变化)——把「升级成本」计入选型,认准你锁定版本的文档。

资源地址说明
官网 & 指南dioxuslabs.com(learn/0.7)按版本号的 Guide,教程成体系
API 文档docs.rs/dioxus锁定你的版本看,一切以此为准
源码 & 示例github.com/DioxusLabs/dioxus(examples/todos / router / fullstack 等可跑范例
CLIdx(cargo binstall dioxus-cli)dx new 脚手架、dx serve 热重载
迁移dioxuslabs.com/learn/0.7/migration升级到 0.7 的破坏性变更清单

学习路径建议:dx new 生成模板,跑官方 examples/ 里的 todosfullstack(正好覆盖本文的信号 + server functions),再回头对照各节。遇到 API 对不上,第一反应是「看 0.7 的 docs.rs / Guide」——Dioxus 的锅九成是版本漂移。


一句话收束

Dioxus = React 心智、Rust 身体、一份代码多端:组件 + RSX + 信号,读即订阅、改即精确更新;桌面今天走系统 WebView(与 Tauri 同底座,中文/IME 省心、但要吃三平台差异),自绘的 Blitz 是未来。给「前端背景、想 all-in Rust、愿意追新」的团队;在 CMX 语境里,它更是「未来若要 Rust 全栈前端」的候选,而非当下替代 Tauri 的理由。

参考:dioxuslabs.com(learn/0.7、blog)、docs.rs/dioxus 与 docs.rs/dioxus-desktop、github.com/DioxusLabs/dioxus(examples)。版本以 2026-09 的 0.7.x 线为准;凡涉及具体 API,请以你锁定版本的 docs.rs / Guide 为准,勿跨版本照抄。

Logo

一站式 AI 云服务平台

更多推荐