#用户界面 #Web 框架 #同构 #Web UI #响应式 #全栈 #反应式

leptos

Leptos 是一个全栈、同构的 Rust Web 框架,利用细粒度响应性来构建声明式用户界面。

81 个版本

0.7.0-preview2 2024 年 4 月 29 日
0.7.0-beta22024 年 8 月 15 日
0.7.0-beta2024 年 7 月 24 日
0.6.14 2024 年 8 月 14 日
0.0.19 2022 年 11 月 27 日

#8Web 编程

Download history 8262/week @ 2024-05-04 8688/week @ 2024-05-11 8545/week @ 2024-05-18 9375/week @ 2024-05-25 10213/week @ 2024-06-01 7358/week @ 2024-06-08 8743/week @ 2024-06-15 9023/week @ 2024-06-22 5844/week @ 2024-06-29 6631/week @ 2024-07-06 10121/week @ 2024-07-13 11784/week @ 2024-07-20 12873/week @ 2024-07-27 10897/week @ 2024-08-03 12723/week @ 2024-08-10 10872/week @ 2024-08-17

49,388 每月下载量
用于 162 个包 (143 个直接使用)

MIT 许可证

2MB
40K SLoC

Leptos Logo

crates.io docs.rs Discord Matrix

网站 | 书籍 | Docs.rs | 沙盒 | Discord

您可以在 awesome-leptos 找到有用的库和示例项目列表。

当前 main 分支正在进行重大更改,以准备 0.7 版本的发布。对于稳定版本,请使用 v0.6.13 标签

Leptos

use leptos::*;

#[component]
pub fn SimpleCounter(initial_value: i32) -> impl IntoView {
    // create a reactive signal with the initial value
    let (value, set_value) = create_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! {
        <div>
            <button on:click=clear>Clear</button>
            <button on:click=decrement>-1</button>
            // text nodes can be quoted or unquoted
            <span>"Value: " {value} "!"</span>
            <button on:click=increment>+1</button>
        </div>
    }
}

// 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) = create_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! {
        <SimpleCounter initial_value=3 />
    })
}

关于框架

Leptos 是一个全栈、同构的 Rust Web 框架,利用细粒度响应性来构建声明式用户界面。

这是什么意思?

  • 全栈:Leptos 可以用于构建在浏览器中运行(客户端渲染)的应用程序、在服务器上运行(服务器端渲染),或者在服务器上渲染 HTML 然后在浏览器中添加交互性(服务器端渲染与解冻)。这包括对数据(Resource)和 HTML(有序或无序流 <Suspense/> 组件)的 HTTP 流的支持。
  • 同构:Leptos 提供了用于编写同构 服务器函数 的原语,即可以在客户端或服务器上以“相同形状”调用的函数,但仅在服务器上运行。这意味着您可以编写仅适用于服务器的逻辑(数据库请求、身份验证等),与将消费它的客户端组件并排编写,并像在浏览器中运行一样调用服务器函数,而无需创建和维护单独的 REST 或其他 API。
  • Web:Leptos 基于 Web 平台和 Web 标准。该 路由器 设计用于使用 Web 基础知识(如链接和表单)并在其之上构建,而不是试图取代它们。
  • 框架:Leptos 提供了构建现代 Web 应用所需的大部分内容:响应式系统、模板库和可在服务器端和客户端同时工作的路由器。
  • 细粒度响应性:整个框架都是基于响应式原语构建的。这允许代码具有极低的开销且性能出色:当响应式信号值发生变化时,它可以更新单个文本节点、切换单个类或从 DOM 中删除元素,而不需要运行其他任何代码。(因此,没有虚拟 DOM 的开销!)
  • 声明式:告诉 Leptos 您希望页面看起来如何,然后让框架告诉浏览器如何实现。

了解更多

以下是一些关于学习 Leptos 的资源

nightly 注释

大多数示例都假设您正在使用 nightly 版本的 Rust 和 Leptos 的 nightly 功能。要使用 nightly Rust,您可以将工具链全局设置或针对每个项目设置。

要将 nightly 设置为所有项目的默认工具链(如果您尚未这样做,还可以添加将 Rust 编译为 WebAssembly 的功能)

rustup toolchain install nightly
rustup default nightly
rustup target add wasm32-unknown-unknown

但是,如果您只想在您的 Leptos 项目中使用 nightly,请添加包含以下内容的 rust-toolchain.toml 文件

[toolchain]
channel = "nightly"
targets = ["wasm32-unknown-unknown"]

nightly 功能启用了对信号(信号、memo 或衍生信号)的访问和设置的功能调用语法,而不是 .get().set()。这导致了一个一致的心理模型,其中访问任何类型的响应式值(信号、memo 或衍生信号)始终表示为函数调用。这只有在 nightly Rust 和 nightly 功能下才可行。

cargo-leptos

cargo-leptos 是一个构建工具,旨在简化构建同时运行在客户端和服务器上的应用程序,并实现无缝集成。目前,要开始实际的 Leptos 项目,最佳方式是使用 cargo-leptos 和我们为 ActixAxum 提供的启动模板。

cargo install cargo-leptos
cargo leptos new --git https://github.com/leptos-rs/start
cd [your project name]
cargo leptos watch

在浏览器中打开 http://localhost:3000/

常见问题解答

这个名字是怎么回事?

Leptos(λεπτός)是古希腊语中的一个词,意为“轻薄、精致、细腻”。对我来说,作为一个古典学者而不是狗的主人,它让我联想到驱动框架的轻量级反应式系统。我后来了解到,这个单词也是医学名词“莱姆病”(leptospirosis)的词根,这是一种影响人类和动物的血液感染……抱歉。在创建这个框架的过程中,没有狗受到伤害。

它准备好了吗?

人们通常问这个问题有三个意思。

  1. API是否稳定?也就是说,我是否需要从Leptos 0.1重写到0.2、0.3、0.4,或者我现在就可以编写它,并从新版本的新功能和更新中受益?

API基本上已经确定。我们正在添加新功能,但我们对于类型系统和模式所处的位置非常满意。我不期望在架构方面对您的代码进行重大破坏以适应未来的版本。

  1. 有虫子吗?

是的,我确信有。您可以从我们问题跟踪器的状态中看出,虫子并不多,并且通常解决得相当快。但当然,您可能会遇到需要框架级别修复的情况,这些修复可能不会立即解决。

  1. 我是消费者还是贡献者?

这可能是最大的一个问题:“准备好了”意味着对库有一定的定位:您基本上可以使用它,而无需任何特殊了解其内部或贡献的能力。每个人在他们的堆栈中都有这种水平:例如,我(@gbj)目前没有能力或知识贡献像 wasm-bindgen 这样的事情:我仅仅依靠它工作。

目前社区中有多个人在工作中的内部应用中使用Leptos,他们也成为了重要的贡献者。我认为这是现在的正确生产使用水平。可能有一些您需要的功能缺失,您可能最终会构建它们!但对于内部应用,如果您愿意在过程中构建和贡献缺失的部分,框架现在肯定可用。

我可以用它来创建本地GUI吗?

当然可以!显然,view 宏用于生成DOM节点,但您可以使用反应式系统轻松地驱动任何使用与DOM类似的对象导向、基于事件回调的框架的本地GUI工具包。原则是相同的

  • 使用信号、派生信号和备忘录来创建您的反应式系统
  • 创建GUI小部件
  • 使用事件监听器更新信号
  • 创建效果来更新UI

我整理了一个 非常简单的GTK示例,以便您可以了解我的意思。

为0.7开发的新渲染方法支持“通用渲染”,即它可以使用支持一小套6-8个函数的任何渲染库。(这被视为DOM、GTK等典型保留模式、面向对象风格的GUI工具包的层)。这项未来的渲染工作将允许以与Web框架使用的声明式方法非常相似的方式创建本地UI。

这与Yew有何不同?

Yew是Rust Web UI开发中最常用的库,但Yew和Leptos在哲学、方法和性能方面有几个不同之处。

  • VDOM与细粒度:Yew建立在虚拟DOM(VDOM)模型之上:状态变化会导致组件重新渲染,生成新的虚拟DOM树。Yew将其与之前的VDOM进行对比,并将这些补丁应用到实际的DOM上。组件函数在状态变化时重新运行。Leptos采取了完全不同的方法。组件只运行一次,创建(并返回)实际的DOM节点,并设置一个反应式系统来更新这些DOM节点。

  • 性能:这带来了巨大的性能影响:Leptos在创建和更新UI方面都比Yew快得多。

  • 服务器集成:Yew 是在一个以浏览器渲染的单页应用(SPA)为主导的时代创建的。虽然 Leptos 支持客户端渲染,但它还专注于通过服务器功能以及多种提供 HTML 的方式与您的应用程序的后端集成,包括乱序流。

  • 这与 Dioxus 有何不同?

与 Leptos 一样,Dioxus 是一个使用 Web 技术构建 UI 的框架。然而,在方法和功能上存在显著差异。

  • 虚拟 DOM 与细粒度:虽然 Dioxus 拥有高性能的虚拟 DOM(VDOM),但它仍然使用粗粒度/组件范围的反应性:更改状态值会重新运行组件函数,并将旧 UI 与新 UI 进行比较。Leptos 组件使用不同的思维模型,创建(并返回)实际的 DOM 节点,并设置一个反应性系统来更新这些 DOM 节点。

  • Web 与桌面优先级:Dioxus 在全栈模式中使用 Leptos 服务器功能,但没有基于 <Suspense> 的支持进行 HTML 渲染流等,也没有与整体 Web 性能相同的关注点。Leptos 倾向于优先考虑整体 Web 性能(流式 HTML 渲染、较小的 WASM 二进制大小等),而 Dioxus 在构建桌面应用程序时具有无与伦比的经验,因为您的应用程序逻辑作为原生 Rust 二进制运行。

  • 这与 Sycamore 有何不同?

Sycamore 和 Leptos 都受到了 SolidJS 的很大影响。到目前为止,Leptos 拥有更大的社区和生态系统,并且发展更加活跃。其他差异

  • 模板 DSL:Sycamore 使用自定义模板语言为其视图,而 Leptos 使用类似 JSX 的模板格式。
  • 'static 信号:Leptos 的主要创新之一是创建了 Copy + 'static 信号,具有极佳的易用性。Sycamore 正在采用相同的模式,但尚未发布。
  • Perseus 与服务器功能:Perseus 元框架提供了一种有见地的构建包含服务器功能 Sycamore 应用程序的方法。Leptos 相反,在框架的核心提供了如服务器功能等原语。

依赖关系

~19–35MB
~577K SLoC