Dioxus基础介绍和创建组件
嘿,开发者朋友!想象一下:你写一份代码,就能同时跑在:
网页浏览器 、Windows/Mac 电脑 、安卓/iOS 手机
而且性能飞快、代码整洁、还完全开源免费!这不是梦,这是 Dioxus 的日常操作!
什么是 Dioxus?
简单说:Dioxus = React 的灵魂 + Rust 的肌肉 + Flutter 的野心
它是一个用 Rust 语言写的 UI 框架,让你像搭乐高一样,快速构建跨平台应用。
来看个“击掌计数器”小 demo
use dioxus::prelude::*;pub fn App() -> Element {let mut count = use_signal(|| 0); // 计数器状态rsx! {h1 { "击掌计数器:{count}" }button { onclick: move |_| count += 1, "高高举起!" }button { onclick: move |_| count -= 1, "低低落下!" }}
}
点一下“高高举起”,数字 +1;点“低低落下”,数字 -1。一个简单的交互式网页,就这么写好了! 关键是:这段代码不仅能跑在网页上,还能打包成桌面应用、手机 App!一套代码,全平台通吃!
Dioxus 像谁?又不像谁?
你可能用过 Flutter 或 React。Dioxus 和它们是“远房亲戚”,但有自己的“独门绝技”:
对比项 | Flutter | React | Dioxus |
---|---|---|---|
语言 | Dart | JavaScript | Rust |
渲染 | 自绘引擎 | DOM | HTML + CSS |
性能 | 好 | 一般 | 原生级飞快 |
跨平台 | 是 | 主要是 Web | Web + 桌面 + 移动 |
Dioxus 不造轮子,它用浏览器的 HTML/CSS,但让 Rust 来驱动逻辑,快得离谱,稳得安心。
它怎么做到“一次编写,到处运行”?
Dioxus 的秘诀是:一个核心,多种“皮肤”
- 写代码时,你只关心逻辑和 UI
- 编译时,Dioxus 自动帮你生成:Web 版、桌面版、移动版(未来支持)
就像一个“变形金刚”,同一颗大脑,换不同外壳,适应不同战场!
为什么开发者爱 Dioxus?
简单到像写网页
语法像 React 的 JSX,但更安全(Rust 编译时检查):
#[component]
fn Hello(name: String) -> Element {rsx! { h1 { "你好,{name}!" } }
}
状态管理超智能
用 use_signal
,数据一变,界面自动刷新,不用手动 setState!
let mut count = use_signal(|| 0);
// 只要 count 改了,页面自动重绘
能“钻到底层”搞事情
Rust 的最大优势:直接调系统 API!
#[cfg(web)]
web_sys::alert("这是网页!");#[cfg(target_os = "android")]
jni::call_java_method();
想调摄像头?想读文件?想接蓝牙?Rust 都能干!
Dioxus 给你配了哪些神装?
- 路由系统:页面跳转,轻松搞定
- 服务端函数:前端直接调后端,安全又方便
- 资源管理:图片、字体自动优化
- 热重载:改代码,秒刷新,开发爽到飞起
- 全栈支持:前后端一起写,像 Next.js 一样丝滑
稳定吗?能用于生产吗?
目前是 0.6 版本,还没到 1.0,所以还会有些小变动。但别慌!
- 核心 API 已基本稳定
- 每次升级都有详细迁移指南
- 社区活跃,更新飞快
小建议:小项目可以大胆上,大项目建议等 1.0,或者边用边跟进。
开始使用 Dioxus
开始使用 Dioxus 非常快,一分钟到两分钟就能搞定!我们来一步步带你 setup 环境,轻松开启你的第一个跨平台应用之旅。
选择一个代码编辑器
选你最喜欢的编辑器就行!我们强烈推荐 VSCode,因为 Dioxus 官方提供了一个专属的 VSCode 扩展,能大幅提升开发体验。
不过别担心——我们的构建工具 dx
是独立运行的,支持任何编辑器。
安装 Rust-Analyzer(代码助手)
Dioxus 与 Rust-Analyzer(Rust 的语言服务器插件)集成得非常好,它能提供:
- 智能语法高亮
- 代码跳转
- 折叠功能
- 自动补全
- 错误提示
总之,让你写 Rust 像写 JavaScript 一样丝滑!
安装 Rust
前往 https://www.rust-lang.org 下载并安装 Rust 编译器。
我们推荐使用 rustup
来管理 Rust 环境(这是最标准的方式)。
安装完成后,请确保添加以下两个关键组件:
# 安装稳定的 Rust 工具链
rustup toolchain install stable# 添加 WebAssembly 目标,用于 Web 开发
rustup target add wasm32-unknown-unknown
运行以下命令安装 cargo-binstall
:
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
或者你也可以用其他方式安装:
# 使用 Homebrew(macOS/Linux)
brew install cargo-binstall# 或者从源码安装
cargo install cargo-binstall
安装 Dioxus CLI 工具
Dioxus 由两部分组成:
dioxus
crate:核心框架(你写代码时依赖它)dx
工具:命令行工具,用于构建、运行、打包应用
如果你想开发 Web 或移动应用,或者想使用热重载、自动打包等功能,就必须安装 dx
工具。
推荐方式:使用预编译二进制安装(快!)
cargo binstall dioxus-cli
备选方式:从源码编译安装(慢!)
cargo install dioxus-cli
注意:从源码安装可能需要几分钟,尤其在网络不佳时。我们强烈推荐使用
cargo-binstall
。如果安装时报 OpenSSL 错误,请确保你已安装 这里列出的依赖项。
接下来,你可以:
dx init # 初始化新项目
dx serve # 启动开发服务器(带热重载)
dx build # 构建生产版本
来创建你的第一个 Dioxus 应用!
第一步:创建新项目
打开你的终端(就是那个黑乎乎的命令行窗口),输入这行命令:
dx new hot_dog
然后,系统会问你几个问题,咱们一个一个回答:
- 选个模板(Template):
Bare-bones
:极简模式,只给你一个空文件,适合想从零开始的“硬核玩家”。Jumpstart
:帮你搭好架子,有组件、有结构,适合想快速上手的“效率党”。Workspace
:高级模式,适合要做大项目的“架构师”。
我们选 Bare-bones!因为我们的“HotDog 狗图鉴”不复杂,一个文件就能搞定!
-
要不要做全栈网站?
→ 选false
(不要)(我们先做前端,以后再加后端) -
要路由(Router)吗?
→ 选false
(先不要)(虽然以后会加,但现在先专注“看狗”) -
要用 TailwindCSS 吗?
→ 选false
(不用)(我们自己写 CSS,更可控!) -
默认平台是?
→ 选 Web(网页版)(我们要在浏览器里看狗!)
小知识:你其实不一定要用
dx new
来创建项目!
因为 Dioxus 项目本质就是 Rust 项目,你也可以用cargo new
来创建,就像造一辆车,dx
是自动生产线,cargo
是手工打造。
第二步:运行项目!
项目创建好了,进入文件夹:
cd hot_dog
然后启动服务器:
dx serve
这时候,Dioxus 会:
- 编译你的代码(就像把零件组装成车)
- 启动一个本地服务器(就像把车开到你家楼下)
打开浏览器,访问这个地址: http://127.0.0.1:8080
一开始会看到一个“加载中…”的页面,别急,等几秒……
成功!你会看到 Dioxus 的默认欢迎页!
恭喜你!你的第一个 Dioxus 应用,成功上线!
第三步:看看项目长啥样?
用编辑器打开 hot_dog
文件夹,你会看到这些文件:
├── Cargo.lock # 依赖锁文件(别动它)
├── Cargo.toml # 项目配置文件(很重要!)
├── Dioxus.toml # Dioxus 专属配置
├── README.md # 项目说明
├── assets/ # 放图片、图标、CSS 的地方
│ ├── favicon.ico # 网页标签上的小图标
│ ├── header.svg # 头部图片
│ └── main.css # 样式文件
└── src/ # 所有代码都在这里!└── main.rs # 主程序入口!
是不是有点像手机文件夹?src
就是“应用程序”,assets
就是“相册和铃声”。
重点文件解析
1. Cargo.toml
—— 项目的“身份证”
这个文件告诉电脑:“我要用哪些工具来干活”。
比如,它会写:
[dependencies]
dioxus = { version = "0.6.0" }
意思是:“我用的是 Dioxus 框架,版本 0.6.0”。
它还定义了不同平台的“开关”:
[features]
default = ["web"]
web = ["dioxus/web"]
desktop = ["dioxus/desktop"]
意思是:
- 默认跑在网页上(web)
- 如果你想打包成桌面应用,就加
--features desktop
dx serve --platform desktop
就是告诉它:“我要在电脑上运行!”
2. Dioxus.toml
—— Dioxus 的“私人管家”
这个文件专门管 Dioxus 自己的事,比如:
- 打包时包含哪些文件
- 部署到哪里
但从 Dioxus 0.6 开始,很多功能被简化了,我们暂时不用动它。
小白可以把它当“背景板”,以后再研究。
3. assets
文件夹 —— 你的“资源仓库”
这里放:
- 图片(.png, .jpg)
- 图标(.ico)
- 样式表(.css)
- 字体、音频……
Dioxus 提供了一个叫 asset!()
的魔法宏(以后会讲),能自动帮你打包这些资源。
建议:所有资源都放这里,别乱扔,不然以后找不着!
4. main.rs
—— 程序的“心脏”
这是整个应用的入口,就像电影的开场镜头。
它的代码长这样:
use dioxus::prelude::*; // 引入所有 Dioxus 工具包fn main() {dioxus::launch(App); // 启动!从 App 组件开始
}
main
函数是 Rust 程序的“开机键”,一运行就从这里开始。
launch(App)
的意思是:“把 App
这个组件画到屏幕上”。
第四步:从“零”开始!
Bare-bones 模板给了我们一点初始代码,但我们要从最干净的状态开始!
所以,我们把原来的“英雄组件”删掉,把 App
变成最简单的样子:
#[component]
fn App() -> Element {rsx! { "HotDog!" }
}
现在,浏览器里只会显示一个大字: HotDog!
现在,我们的 HotDog 应用已经搭好架子了,是时候开始造零件了!
在 Dioxus 里,我们不叫它“功能模块”或“页面片段”,我们叫它——组件(Component)。
什么是组件?
在 Dioxus 的世界里,一切皆组件!
一个按钮、一张狗图、一个标题栏……全都是组件。
它们长得就像一个普通函数,但加了个魔法标签 #[component]
:
#[component]
fn DogApp(breed: String) -> Element {todo!() // “待办事项”——先占个坑,后面再填
}
这行代码的意思是:
“我是一个组件,名字叫
DogApp
,它需要一个参数:狗的品种(比如柯基、哈士奇),然后它会返回一段界面(Element)。”
组件的“背包”——Props(属性)
每个组件都可以带“行李”,也就是我们说的 Props(属性)。
比如,你想展示一只狗,那你得告诉它:“这是什么品种?”、“名字叫啥?”、“乖不乖?”。
我们先用传统方式定义一个“背包”:
#[derive(Props, PartialEq, Clone)]
struct DogAppProps {breed: String,
}
这就像在说:
“这个组件的背包里,必须装一个叫
breed
的字符串,比如 ‘corgi’。”注意:所有 Props 都要带上
Clone
和PartialEq
,因为 Dioxus 要能“复制”它、还要能“比较”它有没有变。
但!每次都写个结构体太麻烦了……。所以 Dioxus 提供了一个超级便利的宏:#[component]
!
魔法宏:#[component]
—— 让写组件像说话一样简单
有了 #[component]
,你再也不用手动写 Props
结构体了!直接把参数写在函数里,Dioxus 自动帮你打包成“背包”:
#[component]
fn DogApp(breed: String) -> Element {rsx! { "这只狗是 {breed} 品种!" }
}
是不是清爽多了?
这就像你对 Dioxus 说:“我要一个组件,它需要一个 breed
参数”,Dioxus 回答:“好嘞,包在我身上!”
- 做应用时,用
#[component]
宏最方便。- 做库(给别人用的工具)时,建议手动写
Props
,更灵活可控。
Props 是“只读”的——不能改!
如果你玩过 React,那你会觉得 Dioxus 很亲切。
它和 React 一样:Props 是 immutable(不可变的)。
什么意思?
就是你不能在组件内部偷偷改掉传进来的值。
比如这样是不行的:
#[component]
fn DogApp(mut breed: String) -> Element {breed = "金毛".to_string(); // 错误!别乱改别人的行李!rsx! { "{breed}" }
}
Dioxus 每次渲染时,都会把 Props 复制一份(.clone()
),确保你改不掉原始数据,避免“改着改着就乱套”的问题。
就像你朋友把行李箱交给你保管,你不能偷偷把里面的衣服全换成你的……
别担心性能!Dioxus 用了一些聪明的办法让 .clone()
变得非常快,几乎不耗资源。
组件会“反复执行”——别慌,这是正常的!
Dioxus 的组件函数不是只跑一次,而是会反复调用,这叫“重新渲染”(re-render)。
比如:
- 用户点了按钮
- 数据更新了
- 狗狗换品种了
Dioxus 就会再跑一遍你的组件函数,生成新的界面。
举个例子:
#[component]
fn DogApp(breed: String) -> Element {tracing::info!("渲染啦!品种是:{breed}");rsx! { "Breed: {breed}" }
}
第一次传 "corgi"
,打印一次;
第二次传 "husky"
,又打印一次。
但这不是浪费!Dioxus 超聪明,它只在真正需要时才重新渲染。
Dioxus 是怎么决定“要不要重画”的?——Diffing(比对机制)
Dioxus 不会盲目重画,它会做两件事来判断:
1. Props 变了吗?
它会用 ==
比较新旧 Props。如果 breed
从 "corgi"
变成了 "poodle"
,那就重画。
2. 状态更新了吗?
如果你用了 signal.set()
或 signal.write()
,Dioxus 会收到通知:“我变了!快重画!”
比如你有个“点赞数”,点了“+1”按钮,信号一响,组件自动刷新!
而且!Dioxus 比 React 还聪明:
- 所有组件默认自带缓存(memoized),不会瞎重画。
- 它只检查动态内容(比如
{breed}
),静态部分(比如<h1>狗狗图鉴</h1>
)根本不去看。
所以,重渲染又快又省!
把组件拼起来——搭出你的“狗图鉴”
现在我们有了一个个小积木,是时候拼出整个 App 了!
用 rsx! {}
宏,我们可以像写 HTML 一样把组件组合起来:
#[component]
fn App() -> Element {rsx! {Header {}DogApp { breed: "corgi" }Footer {}}
}
这就像在说:
“我的首页(App)由三部分组成:
- 顶部标题(Header)
- 中间狗图(DogApp),品种是柯基
- 底部版权(Footer)”
每个组件各司其职,互不干扰,想改哪个就改哪个。
组件的五大要点
概念 | 通俗解释 | 小贴士 |
---|---|---|
组件 | 就是乐高积木,一个功能块 | 用 #[component] 定义 |
Props | 组件的“输入参数”或“背包” | 只读!不能改! |
不可变性 | 传进来的值不能改 | 防止状态混乱 |
重新渲染 | 组件函数会被多次调用 | 正常现象,别慌 |
Diffing | Dioxus 聪明地判断要不要重画 | 快!省!准! |