Co-authored-by: Jeremy Chen <jeremychen@djeremychen.com>
18 KiB
使用单个代码库构建Web、桌面和移动应用,以及更多。零配置启动、集成的热重载和基于信号的状态管理。使用服务器功能添加后端功能,并使用我们的CLI进行捆绑。
fn app() -> Element {
let mut count = use_signal(|| 0);
rsx! {
h1 { "High-Five counter: {count}" }
button { onclick: move |_| count += 1, "Up high!" }
button { onclick: move |_| count -= 1, "Down low!" }
}
}
⭐️ 独特功能:
- 三行代码即可实现跨平台应用(Web、桌面、移动、服务器等)
- 人体工程学的状态管理,结合了React、Solid和Svelte的优点
- 非常高效,由Rust最快的wasm框架 sledgehammer 提供支持
- 集成的捆绑包,可部署到Web、macOS、Linux和Windows
- 还有更多!阅读 Dioxus漫游之旅。
瞬时热重载
使用一个命令 dx serve
,您的应用程序即可运行。编辑您的标记和样式,并实时查看结果。目前Rust代码热重载尚未达到一流水平,但也许可以使用 hot-lib-reloader 实现。
用于Web和桌面部署的捆绑包
只需运行 dx bundle
,您的应用程序将被构建和捆绑,并进行最大化的优化。在Web上,利用 .avif
生成,.wasm
压缩,代码缩小,等等。构建的Web应用程序大小 不到50kb,桌面/移动应用程序小于15mb。
出色的文档
我们花费了大量精力构建清晰、易读和全面的文档。所有HTML元素和监听器都使用MDN文档进行了记录,并且我们的文档站点通过Dioxus本身进行持续集成,以确保文档始终保持最新。查看 Dioxus网站 获取指南、参考资料、示例和更多信息。有趣的事实:我们将Dioxus网站用作新特性的测试平台 - 来看看吧!
开发者体验的重点
Dioxus优先考虑开发者体验,我们为端到端工具链付出了大量努力。我们构建了一个 VSCode扩展,可以自动格式化您的RSX代码,将HTML转换为RSX等等。我们还建立了一个非常强大的 CLI,支持创建新应用程序、提供服务和跨平台捆绑,并且部署正在路上。
社区
Dioxus是一个社区驱动的项目,拥有非常活跃的 Discord 和 GitHub 社区。我们一直在寻求帮助,乐意回答问题并帮助您入门。 我们的SDK 由社区运行,我们甚至有一个 GitHub组织,用于最好的Dioxus crates,这些crate可以获得免费升级和支持。
全职核心团队
Dioxus已经从一个副业项目发展成为一个由全职工程师组成的小团队。由于FutrueWei、Satellite.im和GitHub Accelerator项目的慷慨支持,我们能够全职工作在Dioxus上。我们的长期目标是通过提供高质量的付费企业工具使Dioxus自我维持。如果您的公司有兴趣采用Dioxus,并希望与我们合作,请联系我们!
支持的平台
Web
一级支持 |
|
Fullstack
一级支持 |
|
桌面
一级支持 |
|
Liveview
一级支持 |
|
移动
二级支持 |
|
终端
二级支持 |
|
运行示例
该存储库顶层的示例可以通过 cargo run --example <example>
运行。但是,我们建议您下载dioxus-cli并使用 dx serve
运行示例,因为许多示例还支持web。在运行web时,您可以修改Cargo.toml以禁用默认的desktop功能,或者使用
Dioxus与其他框架
我们喜欢Rust生态系统中的所有框架,并享受着Rust生态系统中的创新。事实上,我们的许多项目都与其他框架共享。例如,我们的flex-box库 Taffy 被 Bevy、Zed、Lapce、Iced 等项目使用。
Dioxus侧重于几个与其他框架不同的重点,这些重点使其与其他框架不同:
- 类似React:我们依赖于组件、props和hooks等概念来构建UI,我们的状态管理更接近于Svelte而不是SolidJS。
- HTML和CSS:我们完全依赖HTML和CSS,包括怪癖和全部。
- 渲染器不可知:您可以根据需要将渲染器替换为任何平台,感谢我们的快速VirtualDOM。
- 合作:只要有可能,我们就会拆分出像Taffy、magnanis、include_mdbook和blitz这样的crate,以便生态系统能够共同成长。
Dioxus与Tauri
Tauri是一个用于构建桌面(和即将到来的移动)应用程序的框架,其中前端使用诸如React、Vue、Svelte等的基于web的框架编写。每当需要进行本机工作时,您可以编写Rust函数并从前端调用它们。
-
纯Rust:Tauri的架构将您的UI限制为JavaScript或WebAssembly。使用Dioxus,您的Rust代码在用户的计算机上本地运行,使您可以执行诸如生成线程、访问文件系统等操作,而无需任何IPC。这大大简化了应用程序的架构,并使其更易于构建。您可以使用Dioxus-Web作为前端构建Tauri应用程序。
-
不同的范围:Tauri需要支持JavaScript及其复杂的构建工具链,从而限制了您可以使用的范围。由于Dioxus专注于Rust,我们能够提供额外的实用工具,如服务器函数、高级捆绑和本机渲染器。
-
共享DNA:虽然Tauri和Dioxus是独立的项目,但它们确实共享库,如Tao和Wry:由Tauri团队维护的窗口和webview库。
Dioxus与Leptos
Leptos是用于构建全栈web应用程序的库,类似于SolidJS和SolidStart。两个库在web上有着相似的目标,但有几个关键区别:
-
响应模型:Leptos使用信号作为其基础的响应性,而Dioxus选择使用VirtualDom和重新渲染。虽然从理论上讲,信号更高效,但实际上,由于我们的block-dom模板并没有进行实际的diffing,而是直接重新渲染了UI,Dioxus的VirtualDom的表现与Leptos相比几乎没有什么差异,并且实际上比Leptos更快。
-
控制流:因为Leptos使用信号来实现响应性,所以您只能使用Leptos的原语来进行
for
循环和if
语句。如果您搞错了这一点,您的应用程序将失去响应性,导致难以调试的UI问题。使用Dioxus,您可以使用迭代器、常规的Rustfor
循环和if
语句,您的应用程序仍然是响应式的。在实践中,一个向列表中插入计数器的Dioxus组件可能如下所示:
fn Counters() -> Element {
let mut counters = use_signal(|| vec![0; 10]);
rsx! {
button { onclick: move |_| counters.push(counters.len()), "Add Counter" }
ul {
for idx in 0..counters.len() {
li {
button { onclick: move |_| counters.write()[idx] += 1, "{counters.index(idx)}" }
button { onclick: move |_| { counters.remove(idx); }, "Remove" }
}
}
}
}
}
fn Counters() -> impl IntoView {
let counters = RwSignal::new(vec![0; 10]);
view! {
<button on:click=move |_| counters.update(|n| n.push(n.len()))>"Add Counter"</button>
<For
each=move || 0..counters.with(Vec::len)
key=|idx| *idx
let:idx
>
<li>
<button on:click=move |_| counters.update(|n| n[idx] += 1)>
{Memo::new(move |_| counters.with(|n| n[idx]))}
</button>
<button on:click=move |_| counters.update(|n| { n.remove(idx); })>
"Remove"
</button>
</li>
</For>
}
}
-
Copy
状态: Dioxus 0.1 到 0.4 版本依赖于生命周期来放宽 Rust 的借用检查规则。这对于事件处理程序效果很好,但在异步方面表现不佳。在 Dioxus 0.5 中,我们已经转向了从 Leptos 借鉴来的Copy
状态模型。 -
不同的范围: Dioxus 提供了用于 web、桌面、移动、LiveView 等的渲染器。我们还维护着社区库和跨平台 SDK。这项工作的范围很大,意味着我们的发布速度历来比 Leptos 慢。Leptos 专注于全栈 web,具有 Dioxus 没有的功能,如基于
<Suspense />
的流式 HTML、islands、<Form />
组件和其他特定于 web 的功能。通常情况下,您使用 Leptos 构建的 web 应用程序将占用较小的空间。 -
不同的 DSL: 虽然两个框架都针对 web,但 Dioxus 使用自己的定制 Rust 风格的 DSL 来构建 UI,而 Leptos 使用更类似 HTML 的语法。我们选择了这样做以保留与代码折叠和语法高亮等 IDE 功能的兼容性。通常情况下,Dioxus 倾向于在其 DSL 中使用更多的 "魔法"。例如,dioxus 将自动为您格式化字符串,而 Leptos 可以将字符串拆分为静态和动态段。
Dioxus vs Yew
Yew 是用于构建单页面 web 应用程序的框架,最初是 Dioxus 的灵感来源。不幸的是,Yew 的架构不支持我们想要的各种功能,因此 Dioxus 应运而生。
-
单页面应用程序: Yew 专门设计用于单页面 web 应用程序,并与 web 平台紧密相关联。Dioxus 是全栈和跨平台的,适用于构建 web、桌面、移动和服务器应用程序。
-
开发工具: Dioxus 提供了许多实用工具,如自动格式化、热重载和打包工具。
-
持续支持: Dioxus 在日常基础上积极维护,不断添加新功能和修复错误。
Dioxus vs egui
egui 是 Rust 的跨平台 GUI 库,支持像 Rerun.io 这样的工具。
-
Immediate vs Retained: egui 被设计为在每一帧上重新呈现。这适用于游戏和其他交互式应用程序,但它不会在帧之间保留样式和布局状态。Dioxus 是一个保留的 UI 框架,意味着 UI 只构建一次,然后在帧之间进行修改。这使得 Dioxus 可以使用本地 web 技术,如 HTML 和 CSS,具有更好的电池寿命和性能。
-
可定制性: egui 带有自己的样式和布局解决方案,而 Dioxus 期望您使用内置的 HTML 和 CSS。这使得 dioxus 应用程序可以使用任何 CSS 库,如 Tailwind 或 Material UI。
-
状态管理: egui 的状态管理基于单个全局状态对象。Dioxus 鼓励通过使用组件和属性封装状态,使组件更可重用。
Dioxus vs Iced
Iced 是受 Elm 启发的跨平台 GUI 库。Iced 使用 WGPU 进行本机渲染,并支持使用 DOM 节点的 web。
-
Elm 状态管理: Iced 使用 Elm 的状态管理模型,该模型基于消息传递和减速器。这与 Dioxus 的状态管理模型完全不同,有时可能相当冗长。
-
本地感觉: 由于 Dioxus 使用 webview 作为其渲染器,因此它自动获得本地文本输入、粘贴处理和其他本地功能,如可访问性。Iced 的渲染器目前不实现这些功能,使其感觉不太本地。
-
WGPU: Dioxus 的 WGPU 渲染器目前还不太成熟,尚未准备好供生产使用。Iced 的 WGPU 渲染器要成熟得多,并且正在生产中使用。这使得某些需要 GPU 访问的应用程序可以使用 Iced 构建,而目前无法使用 Dioxus 构建。
Dioxus vs Electron
Dioxus 和 Electron 是两个完全不同的项目,目标相似。Electron 使开发人员能够使用 HTML、CSS 和 JavaScript 等 web 技术构建跨平台桌面应用程序。
-
轻量级: Dioxus 使用系统的本地 WebView - 或者选择性地,一个 WGPU 渲染器 - 来渲染 UI。这使得典型的 Dioxus 应用程序在 macOS 上约为 15mb,而 Electron 则为 100mb。Electron 还提供了一个嵌入式的 chromium 实例,无法像 Dioxus 那样与主机操作系统共享系统资源。
-
成熟度: Electron 是一个成熟的项目,拥有庞大的社区和大量的工具。相比之下,Dioxus 相对于 Electron 来说还很年轻。期望遇到需要额外工作来实现的功能,如 deeplinking 等特性。
贡献
许可证
此项目根据 MIT 许可证 许可。
除非您明确说明,否则您提交的任何贡献都将由您自己有意提交,以 MIT 许可证许可,不附加任何其他条款或条件。