[](https://crates.io/crates/leptos)
[](https://docs.rs/leptos)

[](https://discord.gg/YdRAhS7eQB)
[](https://matrix.to/#/#leptos:matrix.org)
[网站](https://leptos.dev) | [书籍](https://leptos-rs.github.io/leptos/) | [Docs.rs](https://docs.rs/leptos/latest/leptos/) | [演练场](https://codesandbox.io/p/sandbox/leptos-rtfggt?file=%2Fsrc%2Fmain.rs%3A1%2C1) | [Discord](https://discord.gg/YdRAhS7eQB)
你可以在 [`awesome-leptos`](https://github.com/leptos-rs/awesome-leptos) 找到实用的库和示例项目列表。
# Leptos
```
use leptos::*;
#[component]
pub fn SimpleCounter(initial_value: i32) -> impl IntoView {
// create a reactive signal with the initial value
let (value, set_value) = signal(initial_value);
// create event handlers for our buttons
// note that `value` and `set_value` are `Copy`, so it's super easy to move them into closures
let clear = move |_| set_value(0);
let decrement = move |_| set_value.update(|value| *value -= 1);
let increment = move |_| set_value.update(|value| *value += 1);
// create user interfaces with the declarative `view!` macro
view! {
// text nodes can be quoted or unquoted
"Value: " {value} "!"
}
}
// we also support a builder syntax rather than the JSX-like `view` macro
#[component]
pub fn SimpleCounterWithBuilder(initial_value: i32) -> impl IntoView {
use leptos::html::*;
let (value, set_value) = signal(initial_value);
let clear = move |_| set_value(0);
let decrement = move |_| set_value.update(|value| *value -= 1);
let increment = move |_| set_value.update(|value| *value += 1);
// the `view` macro above expands to this builder syntax
div().child((
button().on(ev::click, clear).child("Clear"),
button().on(ev::click, decrement).child("-1"),
span().child(("Value: ", value, "!")),
button().on(ev::click, increment).child("+1")
))
}
// Easy to use with Trunk (trunkrs.dev) or with a simple wasm-bindgen setup
pub fn main() {
mount_to_body(|| view! {
})
}
```
## 关于框架
Leptos 是一个全栈、同构的 Rust web 框架,利用细粒度响应式来构建声明式用户界面。
## 这意味着什么?
- **全栈**:Leptos 可用于构建在浏览器(客户端渲染)、服务器(服务端渲染)运行的应用,或在服务器上渲染 HTML 然后在浏览器中添加交互性(带 hydration 的服务端渲染)。这包括对数据([`Resource`s](https://docs.rs/leptos/latest/leptos/prelude/struct.Resource.html))和 HTML([``](https://docs.rs/leptos/latest/leptos/suspense/fn.Suspense.html) 组件的乱序或顺序流式传输)的 HTTP 流式支持。
- **同构**:Leptos 提供了编写同构 [server functions](https://docs.rs/server_fn/latest/server_fn/) 的原语,即可以在客户端或服务器上以“相同的形式”调用,但仅在服务器上运行的函数。这意味着你可以将服务器端逻辑(数据库请求、身份验证等)与将使用它的客户端组件放在一起编写,并像在浏览器中运行一样调用 server functions,而无需创建和维护单独的 REST 或其他 API。
- **Web**:Leptos 构建在 Web 平台和 Web 标准之上。[router](https://docs.rs/leptos_router/latest/leptos_router/) 旨在利用 Web 基础知识(如链接和表单)并在此基础上构建,而不是试图取代它们。
- **框架**:Leptos 提供了构建现代 web 应用所需的大部分功能:一个响应式系统、模板库,以及一个可在服务器和客户端运行的路由。
- **细粒度响应式**:整个框架由响应式原语构建。这允许以最小的开销实现极高性能的代码:当响应式 signal 的值发生变化时,它可以更新单个文本节点、切换单个类或从 DOM 中移除元素,而无需运行任何其他代码。(因此,没有虚拟 DOM 的开销!)
- **声明式**:告诉 Leptos 你希望页面看起来是什么样,让框架告诉浏览器如何做。
## 了解更多
以下是一些关于了解 Leptos 的更多资源:
- [书籍](https://leptos-rs.github.io/leptos/)(编写中)
- [示例](https://github.com/leptos-rs/leptos/tree/main/examples)
- [API 文档](https://docs.rs/leptos/latest/leptos/)
- [常见错误](https://github.com/leptos-rs/leptos/tree/main/docs/COMMON_BUGS.md)(以及如何修复它们!)
## `cargo-leptos`
[`cargo-leptos`](https://github.com/leptos-rs/cargo-leptos) 是一个构建工具,旨在轻松构建在客户端和服务器上运行的应用,并提供无缝集成。现在开始真正的 Leptos 项目的最佳方式是使用 `cargo-leptos` 和我们的 [Actix](https://github.com/leptos-rs/start) 或 [Axum](https://github.com/leptos-rs/start-axum) 起始模板。
```
cargo install cargo-leptos --locked
cargo leptos new --git https://github.com/leptos-rs/start-axum
cd [your project name]
cargo leptos watch
```
在浏览器中打开 [http://localhost:3000/](http://localhost:3000/)。
## 常见问题
### 这个名字是怎么回事?
_Leptos_ (λεπτός) 是一个古希腊词,意思是“薄、轻、精致、细粒度”。对于我这个古典学家(而不是狗主人)来说,它让人联想到驱动该框架的轻量级响应式系统。我后来才知道,同一个词是医学术语“钩端螺旋体病”的词根,这是一种影响人类和动物的血液感染……我的错。在创建这个框架的过程中,没有狗受到伤害。
### 它可以在生产环境中使用吗?
人们通常这个问题意味着三件事之一。
1. **API 稳定吗?** 即,我是否必须从 Leptos 0.1 到 0.2 到 0.3 到 0.3 重写我的整个应用程序,还是我现在可以编写它并在新版本发布时受益于新功能和更新?
API 基本上已经确定。我们正在添加新功能,但我们对象类型系统和模式的现状非常满意。我不认为未来的版本在架构方面需要对你的代码进行重大的破坏性更改。
2. **有 Bug 吗?**
是的,我确定有。你可以从我们的 Issue 跟踪器的状态中看到,实际上并没有_那么多_Bug,而且它们通常解决得很快。但肯定的是,有时你可能会遇到需要在框架层面修复的问题,这可能不会立即得到解决。
3. **我是使用者还是贡献者?**
这可能是个大问题:“生产就绪”意味着对库的某种取向:你基本上可以使用它,而不需要对其内部原理有任何特殊了解或做出贡献的能力。每个人都在他们的技术栈中的某个层面有这种情况:例如,我 (@gbj) 目前没有能力或知识去为 `wasm-bindgen` 之类的东西做贡献:我只是依赖它能工作。
社区中有几个人现在正在工作中使用 Leptos 构建许多网站,他们也成为了重要的贡献者。可能缺少你需要的功能,你可能最终会构建它们!但是,如果你愿意在这个过程中贡献一些缺失的部分,该框架绝对可用于生产应用程序,特别是考虑到围绕它出现的库生态系统。
### 我可以将其用于原生 GUI 吗?
当然!显然 `view` 宏是用于生成 DOM 节点的,但你可以使用响应式系统来驱动任何使用与 DOM 相同类型的面向对象、基于事件回调框架的原生 GUI 工具包,这非常容易。原理是一样的:
- 使用 signals、derived signals 和 memos 创建你的响应式系统
- 创建 GUI 小部件
- 使用事件监听器更新 signals
- 创建 effects 以更新 UI
0.7 更新最初打算创建一个“通用渲染”方法,允许我们重用大部分相同的视图逻辑来完成上述所有工作。不幸的是,由于 Rust 编译器在构建大规模应用程序时遇到了困难,因为这种方法需要在整个代码库中传播大量的泛型,这目前不得不被搁置。这是一个我期待在未来探索的方法;如果你对这类工作感兴趣,请随时联系。
### 这与 Yew 有什么不同?
Yew 是最常用的 Rust web UI 开发库,但在理念、方法和性能方面,Yew 和 Leptos 之间存在一些差异。
- **VDOM vs. 细粒度:** Yew 基于虚拟 DOM (VDOM) 模型构建:状态更改导致组件重新渲染,生成新的虚拟 DOM 树。Yew 将其与以前的 VDOM 进行 diff,并将这些补丁应用到实际的 DOM。每当状态更改时,组件函数都会重新运行。Leptos 采取了一种完全不同的方法。组件运行一次,创建(并返回)实际的 DOM 节点,并建立一个响应式系统来更新这些 DOM 节点。
- **性能:** 这对性能有巨大的影响:Leptos 在创建和更新 UI 方面比 Yew 快得多。
- **服务器集成:** Yew 创建于浏览器渲染的单页应用 (SPA) 占主导地位的时代。虽然 Leptos 支持客户端渲染,但它也专注于通过 server functions 和多种 HTML 服务模式(包括乱序流式传输)与应用程序的服务器端集成。
### 这与 Dioxus 有什么不同?
像 Leptos 一样,Dioxus 是一个使用 web 技术构建 UI 的框架。然而,在方法和功能上存在显著差异。
- **VDOM vs. 细粒度:** 虽然 Dioxus 有一个高性能的虚拟 DOM (VDOM),但它仍然使用粗粒度/组件作用域的响应式:更改有状态的值会重新运行组件函数并将旧 UI 与新 UI 进行 diff。Leptos 组件使用不同的心智模型,创建(并返回)实际的 DOM 节点并设置响应式系统来更新这些 DOM 节点。
- **Web vs. 桌面优先级:** Dioxus 在其全栈模式下使用 Leptos server functions,但没有相同的基于 `` 的支持,例如流式 HTML 渲染,也没有同样的对整体 web 性能的关注。Leptos 倾向于优先考虑整体 web 性能(流式 HTML 渲染、更小的 WASM 二进制大小等),而 Dioxus 在构建桌面应用程序方面拥有无与伦比的体验,因为你的应用程序逻辑作为原生 Rust 二进制文件运行。
### 这与 Sycamore 有什么不同?
Sycamore 和 Leptos 都深受 SolidJS 的影响。目前,Leptos 拥有更大的社区和生态系统,并且开发更加活跃。其他差异:
- **模板 DSL:** Sycamore 为其视图使用自定义模板语言,而 Leptos 使用类似 JSX 的模板格式。
- **`'static` signals:** Leptos 的主要创新之一是创建了 `Copy + 'static` signals,它具有出色的人体工程学。Sycamore 正在采用相同的模式,但尚未发布。
- **Perseus vs. server functions:** Perseus 元框架提供了一种固执己见的方式来构建包含服务器功能的 Sycamore 应用程序。Leptos 则在框架核心提供了像 server functions 这样的原语。