前言
前面几篇,我们一直在 Web 视角里看 Dioxus:
rsx!怎么写- Signals 怎么管状态
- 组件怎么拆
- 路由怎么组织
- 桌面端为什么也是 WebView,但和 Tauri 写起来不是一个感觉
到了移动端,话题就没法只停留在"语法顺不顺手"了。
因为桌面应用哪怕有点毛边,很多时候还能靠"内部工具""先交付再打磨"撑过去。手机不一样。大家一想到 Android 和 iOS,马上就会问这些更现实的问题:
- 滑动手感怎么样
- 长列表会不会掉帧
- 相机、推送、蓝牙怎么接
- 签名和上架麻不麻烦
所以这篇不聊 "Hello World 能不能亮起来"。那个问题太初级了。真正该问的是:Dioxus Mobile 现在到底能做什么,它又在哪些地方明显还不够。
1. 先把定位说清楚:它不是原生控件路线
如果只记一句话,我建议记这句:
Dioxus Mobile 能做移动应用,但它默认不是原生控件方案,本质上还是移动端 WebView 方案。
按 Dioxus 0.7 官方移动文档现在的表述,移动端支持已经是正式方向,渲染主要有两条路:
- 平台 WebView
- 实验性的 WGPU 渲染器
这件事决定了后面几乎所有判断。
换句话说,Dioxus Mobile 不是:
- Flutter 这种自己管渲染管线的路子
- React Native 这种强调原生控件映射的路子
- SwiftUI / Jetpack Compose 这种平台原生 UI 框架
它更接近这样一套结构:
- 外面是 Android Activity 或 iOS App 容器
- 中间是平台运行时
- 里面显示出来的界面,核心还是 HTML/CSS 那一套结果
- 只是你写它时,用的不是 JS,而是 Rust 的
rsx!
所以如果有人问我"Dioxus Mobile 算不算能做移动端",我的回答会比较克制:
能做,但更像 Rust 版跨平台 WebView App。你别把它脑补成"Rust 版原生移动 UI 框架",这两个预期差得很远。
2. 它怎么跑起来
这个问题拿代码看最省事。
2.1 你写的还是那套熟悉的 Rust 组件
比如下面这段代码,前几篇跟下来的同学应该已经很熟了:
rust
use dioxus::prelude::*;
fn main() {
dioxus::launch(App);
}
#[component]
fn App() -> Element {
let mut keyword = use_signal(|| String::from("Dioxus Mobile"));
let mut clicks = use_signal(|| 0);
rsx! {
div { class: "page",
h1 { "一套 Rust 组件切到移动端" }
input {
value: "{keyword}",
oninput: move |evt| keyword.set(evt.value()),
placeholder: "输入点什么"
}
button {
onclick: move |_| clicks += 1,
"点了 {clicks} 次"
}
}
}
}
这里有个很关键的事实:你没写 Android XML,也没写 SwiftUI / UIKit。
你写的还是:
- Rust 组件
rsx!描述 UI- Signals 管状态
- Rust 闭包处理事件
这也是 Dioxus 最有吸引力的地方。它不是让你为 Android 重写一遍、再为 iOS 重写一遍,而是尽量让你守住一套组件和一套状态逻辑。
2.2 只是运行目标换成了移动端容器
切到移动端之后,Dioxus 不会把这些组件"翻译"成原生按钮和原生输入框。它做的事更接近于:
- Android 侧把应用挂进 Android 容器
- iOS 侧把应用挂进 iOS 容器
- 最后界面仍由 WebView 渲染出来
这就是为什么你在 Web 端已经写好的东西,往往可以直接带过来:
- 页面结构
- CSS 样式
- 组件拆分
- 路由组织
- 大部分状态逻辑
这部分确实很香。尤其是小团队,真的会少很多重复劳动。
2.3 原生能力可以接,但不是白送的
很多人一看到 WebView,就默认它只能做表单和展示页。这个结论也有点过了。
Dioxus 官方文档给的态度很明确:如果框架层没包好某个能力,你可以自己往平台 API 下钻。典型方式大概是这样:
- Web 用
web-sys - Android 用
jni/jni-sys - iOS 用
objc2
比如你想按平台分别走桥接逻辑,可以这么写:
rust
fn call_native_feature() {
#[cfg(target_os = "android")]
{
// 这里可以通过 jni / jni-sys 调 Android 原生能力
}
#[cfg(target_os = "ios")]
{
// 这里可以通过 objc2 调 iOS 原生能力
}
}
所以它不是完全封闭的。
但这里也有个很现实的代价:一旦你开始频繁接原生层,"一套 Rust 代码通吃全部"的轻松感就会明显下降。上层还是统一的,底下已经开始分叉了。
3. Android 和 iOS 的开发链路,比 Web 和桌面重得多
上一篇讲桌面端时,我说过 dx serve --platform desktop 的开发体验已经挺顺了。移动端没那么轻。
3.1 Android:先把工具链扛起来
按 Dioxus 0.7 官方移动文档,Android 侧至少要补这些 Rust 目标:
bash
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
除此之外,还得准备:
- Android Studio
- Android SDK
- Android SDK Command-line Tools
- Android NDK
- CMake
环境变量也要配:
JAVA_HOMEANDROID_HOMENDK_HOMEPATH
说白了,移动端的第一道门槛不是 Dioxus,而是 Android 工具链本来就不轻。你要是没碰过 Android 开发,光把环境配到能稳定编译,就已经够喝一壶了。
3.2 iOS:Xcode 这关也绕不过去
iOS 这边同样如此。
官方文档给出的基础目标安装是:
bash
rustup target add aarch64-apple-ios aarch64-apple-ios-sim
然后你还得有:
- Xcode
- iOS SDK
- Xcode Command Line Tools
- iOS Simulator
做过 Apple 平台开发的人都知道,能编过只是开始。后面还有签名、调试、归档、提审,这些才是折磨人的部分。
3.3 命令入口这件小事,反而很说明问题
这里我专门提一句,免得被旧资料带偏。
很多文章、示例或者大家的旧记忆里,会写:
bash
dx serve --platform android
这个命令并不是错的,很多本地 CLI 版本也确实还能这么用。
但按我在 2026 年 6 月 23 日 核对到的 Dioxus 0.7 官方移动文档,推荐流程更接近:
- 先启动 Android 模拟器或 iOS 模拟器
- 再在项目目录里运行:
bash
dx serve
所以最稳的做法是:先看你本地 dx --help,再对照当前官方文档。
这看起来只是参数形式的小变化,其实很能说明阶段问题。移动端这条链路还在快速收敛,说明它确实在进步,但也说明开发体验还没完全定型。
4. 它更适合做什么 App
只问"能不能做"没太大意义。真正影响选型的是"适不适合做我这个东西"。
如果让我现在给判断,我会把 Dioxus Mobile 更偏向下面几类项目。
4.1 业务型、表单型、信息型 App
比如:
- 企业内部审批 App
- CRM / ERP 的移动入口
- 业务录入工具
- 数据查看面板
- 订单中心、会员中心、消息中心这类页面
这类应用有个共同点:页面逻辑多,表单多,状态多,但最吃重的不是炫技动画,而是业务流转本身。
这刚好落在 Dioxus 相对舒服的区间里。因为你能复用现成的页面结构、Rust 业务逻辑、路由组织,还有一部分 CSS 体系。
4.2 先把多端版本跑起来的 MVP
还有一种场景也很适合:你现在不是要冲顶级移动体验,而是先把业务验证掉。
比如你想尽快把这些先跑通:
- 账户体系
- 列表和详情
- 表单流程
- Web、桌面、移动尽量共用一套逻辑
那 Dioxus 的吸引力就很直接了。它给你的不是某一端做到极致,而是让整体工程复杂度别一下子炸开。
小团队会特别能体会这一点。真正把项目拖死的,很多时候不是功能写不出来,而是仓库越开越多:前端一套、Android 一套、iOS 一套、后端一套,最后同步一个版本都头大。
4.3 团队 Rust 强,前端力量一般
这也是 Dioxus 很明确的一类受众。
如果你的团队:
- Rust 能力不错
- 前端人力一般
- 又不想为了 App 单独引一整套 JS 工程
那 Dioxus Mobile 的思路是说得通的。因为你维护的是一个 Cargo 项目、一套组件模型、一套类型系统,而不是再养一个 React Native、Flutter 或原生移动仓库。
5. 真正难的,不是"跑起来",是"像不像一个像样的移动 App"
这部分我觉得才是重点。
5.1 触控体验不会自动变成原生味
官方移动文档说得很直接:当前并不支持原生 Android 动画和原生控件部件,主要依赖 CSS 动画和样式。
翻成人话就是:它能动,但那个手感不会天然等于原生移动 UI。
比如这些地方,最容易露馅:
- 惯性滚动细节
- 复杂手势反馈
- 下拉刷新手感
- 长列表复用体验
- 系统级转场一致性
这些不是"页面能显示出来"就自动解决的。
如果你的产品特别在意那种原生味,比如 iOS 上滑动时那种跟手程度、列表滚起来的质感、手势和系统转场的契合感,那 Dioxus Mobile 至少在今天还不是个轻松选项。
5.2 性能边界还是会回到 WebView
上一篇桌面篇里我就提过,Dioxus 的很多性能讨论,最后都绕不开 WebView 这块地基。移动端只会更敏感。
因为手机面对的是:
- 更紧的内存约束
- 更明显的发热和功耗问题
- 更容易暴露掉帧的滚动场景
所以如果你的页面主要是表单、详情、普通列表,配一点中轻量动画,通常问题不大。
但如果你做的是:
- 大量复杂手势
- 重动画交互
- 高频图形更新
- 对滚动性能特别挑剔的页面
那就别只盯着"能不能跑起来",而要盯着另一件更实际的事:它能不能长期稳定地跑得像个成熟 App。
5.3 原生能力一多,跨平台收益会被吃掉
理论上,你当然可以靠 jni 和 objc2 去接原生能力。
问题在于,一旦你的 App 很快要接这些东西:
- 推送
- 相机
- 蓝牙
- 文件系统
- 后台任务
- 分享面板
- 生物识别
- 深链接
项目形态就会开始变化。
现实通常会变成:
- Android 一套桥接
- iOS 一套桥接
- Dioxus 上层再包自己的统一接口
你依旧在写 Rust,这没错。但这时候项目复杂度已经不是"轻松共享一切"的那种感觉了。Dioxus 的优势,更多体现在 UI 结构、业务状态和基础交互的复用;它并不等于"所有移动能力都自动跨平台"。
5.4 能出包,不等于能安心上架
很多框架介绍自己时,都容易把"能生成 APK / IPA"说得像"已经具备产品交付能力"。
这两件事差得很远。
移动端真正磨人的地方是:
- 签名
- 权限声明
- 崩溃排查
- 包体控制
- 审核规范
- 原生 SDK 兼容
- 不同系统版本的行为差异
所以如果让我概括 Dioxus Mobile 现在的状态,我会这么说:
开发方向已经打通,工程闭环也在变完整,但离"拿来就能放心上架"的成熟感,还有一段距离。
6. 如果现在就选,它更适合谁
我给一个很直接的判断。
6.1 适合考虑 Dioxus Mobile 的场景
- 你本来就打算用 Rust 做主栈
- 你需要 Web、桌面、移动尽量复用代码
- 你做的是内部系统、业务工具、MVP 或中轻量应用
- 你接受必要时自己下钻到 JNI / Objective-C
- 你更在意工程统一,而不是极致原生体验
6.2 暂时别急着上的场景
- 你要做强原生质感的消费级 App
- 你很依赖复杂手势、长列表和高频动画
- 你需要成熟的移动原生插件生态
- 你希望团队里的移动开发同学拿来就用,而不是一起啃 Rust 加平台桥接
- 你上线目标非常依赖应用商店稳定交付和长期维护
一句话说完:Dioxus Mobile 更像跨平台 Rust 工程方案,不是移动端体验银弹。
7. 总结
Dioxus Mobile 当然不是不能做移动端。恰恰相反,它已经把最关键的路铺出来了:
- Rust 写 UI
- Rust 写状态
- Android 和 iOS 都能作为正式目标
- 需要时也能往 JNI、
objc2这些原生能力下钻
但你也别因为它"已经能跑",就顺手把它想成 Flutter、React Native 或成熟原生方案的平替。现在更准确的说法应该是:
它已经值得 Rust 团队认真评估,但它当前最大的价值仍然是代码统一和工程简化,不是移动体验上的全面领先。
如果你做的是业务型 App、内部工具或者 MVP,我觉得它很值得试。真要做强体验、强原生、重交互产品,那就别只看"跨平台"这三个字,先把触控、性能、原生能力和上架链路想清楚。
如果你已经试过 Dioxus Mobile,也欢迎聊聊你卡在哪一步:工具链、性能,还是原生能力接入。