10 分钟跑起第一个 Dioxus 应用:`dx` CLI、`rsx!` 和热更新好不好用

前言

上一篇主要在回答一个问题:为什么是 Dioxus。

这一篇收窄一点,就做一件事:从零跑起一个 Dioxus 项目。

很多 Rust UI 框架,第一步就容易把人劝退。不是依赖太多,就是工具链太碎,再不然就是能跑起来,但你根本不知道项目结构为什么长这样。

Dioxus 这点还行。它有自己的 dx CLI,创建项目、启动开发服务器、切换平台,至少入门这段路没那么拧巴。

先说清楚,这篇不是官方文档翻译,也不是把 CLI 参数抄一遍。我只讲新手最关心的那条线:

  1. 装好工具
  2. 创建项目
  3. 看懂目录
  4. 改出第一个页面
  5. 跑热更新
  6. 切到桌面端

这 6 步走顺了,后面再学 rsx!、Signals、路由,心里会踏实很多。

1. 先把项目创建出来

1.1 安装 dx CLI

先装 Dioxus 的 CLI:

bash 复制代码
curl -fsSL https://dioxuslabs.com/install.sh | bash

装完以后确认一下:

bash 复制代码
dx --version

这里我建议顺手确认两个环境:

  • rustc --version
  • cargo --version

因为 dx 归根到底还是围绕 Rust 工具链在工作,不是另外搞了一套东西。你可以把它当成 Dioxus 官方给的一层开发入口。

1.2 创建第一个项目

直接新建:

bash 复制代码
dx new hello-dioxus
cd hello-dioxus

然后启动:

bash 复制代码
dx serve

默认会跑 Web 版,本地一般是:

text 复制代码
http://localhost:8080

如果你之前用过 React、Vite 或 Next.js,这一步几乎没有理解成本。区别只是现在写 UI 的语言换成了 Rust。

2. 先别急着写代码,先看懂目录

dx new 生成的项目一般不复杂,大致会长这样:

text 复制代码
hello-dioxus/
├── Cargo.toml
├── Dioxus.toml
├── assets/
│   └── main.css
└── src/
    └── main.rs

先看 3 个地方就够了。

2.1 src/main.rs:应用入口

这个文件就是你第一天最常打交道的地方。应用怎么启动、根组件是什么、页面怎么写,最开始都在这里。

2.2 assets/main.css:样式入口

Dioxus 走的是 WebView / Web 这条路,所以你完全可以把它当成普通前端项目里的 CSS 入口。

这点很实在。它意味着:

  • 你不是在学一套全新样式系统
  • 你熟悉的 class、布局、响应式思路都还能用
  • 后面接 Tailwind CSS 这类工具也比较自然

2.3 Dioxus.toml:Dioxus 的项目配置

这个文件里放的是 Dioxus 自己关心的项目配置,通常会涉及应用名称、资源、打包参数这些东西。

比如后面你要打桌面包、配图标、加资源,很多信息都会写在这里,而不是全塞进 Cargo.toml

3. 默认生成的代码,已经把 Dioxus 的基本味道带出来了

新项目默认给的是一个计数器。别嫌它简单,这段代码已经把最常见的几个概念摆出来了。

rust 复制代码
use dioxus::prelude::*;

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

#[component]
fn App() -> Element {
    let mut count = use_signal(|| 0);

    rsx! {
        div {
            h1 { "Count: {count}" }
            button {
                onclick: move |_| count += 1,
                "Increment"
            }
        }
    }
}

如果你有 React 背景,这里基本可以直接对照着看:

  • #[component]:声明一个组件
  • App() -> Element:组件返回 UI
  • use_signal(|| 0):创建一个响应式状态
  • rsx!:写界面
  • onclick:绑定事件

这里先记一句就行:rsx! 不是模板文件,它就是 Rust 代码的一部分。这个感觉早点建立起来,后面学起来会顺很多。

4. 改出第一个自己的页面

官方默认计数器当然能跑,但有点太素了。我们把它改成一个更像页面的例子:带输入框的欢迎卡片。

rust 复制代码
use dioxus::prelude::*;

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

#[component]
fn App() -> Element {
    let mut name = use_signal(|| String::from("Dioxus"));
    let mut clicks = use_signal(|| 0);

    rsx! {
        div {
            class: "page",

            h1 { "10 分钟跑起你的第一个 Dioxus 应用" }
            p { "这个页面同时演示了 rsx!、事件绑定和 signals。" }

            input {
                value: "{name}",
                oninput: move |evt| name.set(evt.value()),
                placeholder: "输入你的名字"
            }

            button {
                onclick: move |_| clicks += 1,
                "点了我 {clicks} 次"
            }

            p {
                "你好,{name}。欢迎来到 Dioxus。"
            }
        }
    }
}

这个例子里有 3 个点,刚好能把入门阶段最常碰到的东西串起来。

4.1 rsx! 长得像 JSX,但它不是 JSX

你会发现这个宏跟 React 很像:

  • 有标签层级
  • 有属性绑定
  • 有事件处理
  • 有花括号插值

但写两下就会感觉到差异。

举个例子,属性值本质上还是 Rust 表达式:

rust 复制代码
value: "{name}"

事件回调也是 Rust 闭包:

rust 复制代码
oninput: move |evt| name.set(evt.value())

也就是说,你写 UI 的时候并没有离开 Rust。对 Rust 开发者来说,这一点很舒服。

4.2 use_signal 是你最早会反复碰到的状态能力

举个例子,上面的 clicks

rust 复制代码
let mut clicks = use_signal(|| 0);

点击按钮时更新它:

rust 复制代码
onclick: move |_| clicks += 1,

在页面里直接读它:

rust 复制代码
"点了我 {clicks} 次"

这套写法很短,读起来也直观。

如果非要先套一个类比,你可以暂时把它理解成更轻一点的 useState。当然底层不是一回事,Dioxus 走的是细粒度响应式,这个我后面单开一篇讲。

4.3 输入事件的写法,要先适应一下

新手第一眼最容易卡住的,往往是这个:

rust 复制代码
oninput: move |evt| name.set(evt.value())

为什么不是 event.target.value?因为你现在不在浏览器 JavaScript 世界里了,事件对象是 Dioxus 抽象出来的 Rust 类型。

这不算难,但确实要适应一下。

我的建议很简单:先别急着把所有事件类型都搞明白,先把输入框、按钮、列表这些高频场景写顺。后面再回来看事件模型,会轻松不少。

5. 顺手加一点样式,你会更容易进入状态

比如在 assets/main.css 里加一点样式:

css 复制代码
body {
  margin: 0;
  font-family: Inter, system-ui, sans-serif;
  background: #f5f7fb;
  color: #1f2937;
}

.page {
  width: min(720px, calc(100vw - 32px));
  margin: 48px auto;
  padding: 32px;
  background: #ffffff;
  border-radius: 20px;
  box-shadow: 0 18px 60px rgba(15, 23, 42, 0.08);
}

input,
button {
  font: inherit;
  padding: 12px 16px;
  margin-right: 12px;
  border-radius: 12px;
}

再刷新页面,你很快就会意识到,写 Dioxus 的 Web 或桌面 UI,很多时候就是在做前端那套事。

这也是它跟 Makepad 这类 Rust 原生渲染路线差异很大的地方。你不用先学一套新的布局 DSL,再慢慢适应它的规矩。以前写 CSS 的经验,大部分还能接着用。

6. dx serve 的热更新,确实会影响第一印象

这一段我建议你自己手动试一下,因为它很影响你接下来还想不想继续写。

启动:

bash 复制代码
dx serve

然后分别试三种修改。

6.1 改文字内容

比如把:

rust 复制代码
h1 { "10 分钟跑起你的第一个 Dioxus 应用" }

改成:

rust 复制代码
h1 { "我的第一个 Dioxus 页面" }

页面会更新,反馈挺直接。

6.2 改 CSS

比如把卡片圆角从 20px 改成 28px,通常也能很快看到结果。

6.3 改 Rust 结构

比如新增依赖、改 Cargo.toml、调整大的类型定义,这种就别指望跟改 CSS 一样了,本质上还是重新编译。

所以我对 Dioxus 热更新的评价很简单:

  • rsx! 内容,体验不错
  • 改样式,体验不错
  • 改小块逻辑代码,通常也还行
  • 改工程结构和依赖,老老实实等编译

这很正常。它毕竟不是脚本语言,底层还是 Rust 编译链路。

7. 同一个项目切到桌面版,这一步最容易让人记住 Dioxus

Web 跑通以后,直接切桌面版:

bash 复制代码
dx serve --platform desktop

如果环境没问题,你会看到一个桌面窗口弹出来,里面就是刚才那套页面。

有意思的不是"它能弹个窗",而是你会很直观地感受到:

刚才那套组件、状态、样式,几乎没怎么改,就到了另一个平台。

所以我一直觉得,Dioxus 的重点不是"Rust 也能写页面",而是同一套 Rust UI 可以继续往 Web、桌面、移动这几个方向走。

当然,桌面端不是没有现实约束。它当前主流路线依然是 WebView,所以:

  • 原生感不一定比 Makepad 强
  • 能力覆盖不一定比 Tauri 广
  • 最终体验仍然受平台 WebView 影响

但如果只看第一天上手的感受,这一步确实挺加分。

8. 新手最容易踩的几个点

8.1 不要把它当成"Rust 版 HTML"

rsx! 看起来像标签,但你应该把它理解成 Rust 里的声明式 UI 语法,而不是模板文件。

这个心智转不过来,后面看条件渲染、列表渲染、组件组合时会一直拧巴。

8.2 状态是 Rust 值,不是随手乱改的动态对象

在 React 里,很多人已经习惯了"对象一包,状态一塞"。到了 Rust 这里,类型约束会逼着你把东西想清楚一点。

这不是坏事。前面会慢一点,后面项目大了反而稳。

8.3 热更新很好,但不要把它神化

很多文章会把"Rust 也能热更新"讲得很神。实际体验当然比纯 cargo run 强,但边界还是有的。

说白了,它已经够你日常改页面了,但还没到前端脚本生态那种想改啥就秒回的程度。

预期摆正,体验反而更舒服。

总结

如果只看第一天上手,Dioxus 给我的感觉是:比我预想里顺,很多地方也确实像 React;但一碰到状态和类型,Rust 的味道马上就回来了。

这一篇我们做了 6 件事:

  1. 安装 dx
  2. 创建项目
  3. 看懂目录
  4. 改出第一个带状态的页面
  5. 试了热更新
  6. 切到了桌面端

写到这里,你其实已经跨过了 Dioxus 入门最关键的一步:不是知道它有这么个框架,而是真的把它跑起来了。

下一篇我会单独拆 rsx!:条件渲染怎么写、列表渲染怎么写、属性绑定和 JSX 到底哪里一样,哪里不一样。这个东西弄明白了,后面看组件和路由会轻松很多。

如果你已经跑过 Dioxus,第一个让你觉得"哦,这个框架有点意思"的瞬间是什么?评论区聊聊。

相关推荐
奋斗吧程序媛1 小时前
补充一个小知识点:有关@click.native
前端·vue.js
触底反弹1 小时前
🚀 手把手用 HTML5 Canvas 从零打造飞机大战游戏,代码全开源!
前端·javascript·canvas
DJ斯特拉1 小时前
axios快速使用
开发语言·前端·javascript
还有多久拿退休金1 小时前
Ant Design Tree 搜索定位避坑指南:虚拟滚动下如何实现高亮与精准定位
前端·react.js
小月土星1 小时前
CSS 3D 从入门到炫技:手把手教你写一个旋转立方体
前端·css
Hilaku2 小时前
AI 写代码越快,为什么 Code Review 越不能省?
前端·javascript·程序员
sugar__salt2 小时前
从网页小游戏到数据可视化:掌握 HTML5 Canvas 核心能力
前端·信息可视化·html5
北极星日淘3 小时前
前端 i18n 中日双语交互 + 翻译客服接口联动方案|日系海淘平台中文友好化开发实战
前端·交互
現実逃避と3 小时前
WIN10 Edge连续关闭多个标签页导致资源管理器崩溃临时解决办法
前端·edge