十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Leptos Counter 示例全解析:用 Rust 与 WASM 构建客户端渲染计数器应用

Leptos Counter 示例全解析:用 Rust 与 WASM 构建客户端渲染计数器应用 Leptos Counter 示例全解析用 Rust 与 WASM 构建客户端渲染计数器应用【免费下载链接】leptosBuild fast web applications with Rust.项目地址: https://gitcode.com/GitHub_Trending/le/leptos本文以 leptos 仓库中的 examples/counter 为例完整讲解如何在客户端渲染CSR模式下用 Rust 编写组件、使用响应式信号signal与事件处理并通过 Trunk 构建为 WebAssembly 应用运行在浏览器中。读完本文你将掌握 Leptos 最核心的#[component]组件写法、signal读写模式、view!宏语法、浏览器端挂载方式以及如何在真实浏览器中对其做 DOM 级自动化测试。示例概览一个最简单的 Leptos 应用长什么样examples/counter是 leptos 仓库中最基础的入门示例它在纯客户端渲染的 WebAssembly 应用中实现了一个计数器包含 Clear、−1、1 三个按钮和一个显示Value: N!的文本节点。整个示例由三部分构成文件作用examples/counter/src/lib.rs定义可复用的SimpleCounter组件组件库部分examples/counter/src/main.rs应用入口初始化日志并把组件挂载到页面examples/counter/index.htmlTrunk 构建的 HTML 模板声明 wasm 与图标资源examples/counter/tests/web.rs基于wasm-bindgen-test的浏览器内测试examples/counter/Cargo.toml依赖与 release 优化配置从源码结构看这是 leptos 官方推荐的库 入口分离结构把组件放在lib.rs里导出main.rs只负责挂载这样组件可以在测试中直接复用tests/web.rs 中正是通过use counter::*引入组件进行测试的。环境准备与快速启动示例 README 明确给出了最简启动命令trunk serve --open该命令会启动 Trunk 开发服务器并自动在浏览器中打开页面。由于这是一个 CSR 应用trunk负责把 Rust 源码编译成wasm32-unknown-unknown目标并作为前端资源提供。完整的运行前提如下安装 Rust 工具链并切换到 nightly示例目录下的 rust-toolchain.toml 已声明targets [wasm32-unknown-unknown]确保该 target 已通过rustup target add wasm32-unknown-unknown安装安装 Trunkcargo install trunk进入示例目录执行trunk serve --open。更详细的通用示例运行说明见 examples/README.md。此外每个示例的 Makefile.toml 都extend了 examples/cargo-make/main.toml 等任务文件因此也可以用cargo-make执行cargo make ci、cargo make start、cargo make stop来搭建、运行和清理示例进程这是 CI 中使用的可选方式。index.htmlTrunk 如何知道要编译什么!doctype html html head link>use leptos::prelude::*; /// A simple counter component. /// /// You can use doc comments like this to document your component. #[component] pub fn SimpleCounter( /// The starting value for the counter initial_value: i32, /// The change that should be applied each time the button is clicked. step: i32, ) - impl IntoView { let (value, set_value) signal(initial_value); view! { div button on:clickmove |_| set_value.set(0)Clear/button button on:clickmove |_| *set_value.write() - step-1/button spanValue: {value} !/span button on:clickmove |_| set_value.update(|value| *value step)1/button /div } }要点拆解组件即函数#[component]把普通函数转换为 Leptos 组件函数的普通参数initial_value: i32、step: i32就是组件的属性props在使用处通过SimpleCounter initial_value0 step1/传入返回impl IntoView组件返回值是实现了IntoViewtrait 的类型view!宏生成的HtmlElement满足这一约束doc 注释即组件文档源码注释说明你可以在组件上用文档注释记录用途IDE 与文档生成工具都能直接受益signal(initial_value)创建一个由i32初始值驱动的响应式信号返回读写元组(ReadSignal, WriteSignal)。signal是 leptos 响应式系统的核心 API其实现位于 reactive_graph/src/signal.rs底层由reactive_graph提供信号读取/写入的同步追踪机制UI 依赖的信号变化会自动触发相关视图更新。三种信号写入方式计数器示例在一个组件里演示了WriteSignal的三种典型用法这也是实战中最常用的三种写入 API写法代码行为set()set_value.set(0)直接整体覆盖为0用于 Clear 按钮write()*set_value.write() - step返回mut i32原地修改值再写回用于 −1 按钮update()set_value.update(\|value\| *value step)传入闭包对当前值做任意变换用于 1 按钮视图模板view!宏与事件绑定view!是 leptos 的 JSX 风格模板宏在src中通过leptos::prelude::*引入。以上组件为例view! { div button on:clickmove |_| set_value.set(0)Clear/button spanValue: {value} !/span ... /div }文本节点Clear这类字符串字面量直接渲染为文本{value}表示把ReadSignali32作为响应式表达式插入当信号值变化时该文本节点会自动更新——这就是响应式在视图层的体现事件绑定on:clickmove |_| ...是标准事件绑定语法on:后跟 DOM 事件名值为闭包。由于闭包要捕获set_value用move关键字转移所有权_是事件参数这里不需要MouseEvent本身表达式插值{value}之外Value: 与!是静态文本三者共同组成一个动态文本节点。入口与挂载main.rs 的职责use counter::SimpleCounter; use leptos::prelude::*; pub fn main() { _ console_log::init_with_level(log::Level::Debug); console_error_panic_hook::set_once(); mount_to_body(|| { view! { SimpleCounter initial_value0 step1/ } }) }入口做了三件事初始化日志console_log::init_with_level(log::Level::Debug)把log输出转发到浏览器 console便于调试安装 panic 钩子console_error_panic_hook::set_once()让 Rust panic 以可读形式显示在 console 中否则 wasm 中的 panic 信息会很难定位挂载根组件mount_to_body(|| view! { SimpleCounter initial_value0 step1/ })把组件渲染进body。mount_to_body定义在 leptos/src/mount.rspub fn mount_to_body同文件还提供mount_to挂载到指定元素并返回UnmountHandle测试中用来挂到测试容器与mount_to_renderer等挂载 API。main.rs里的main()不是fn main() - Result(), Boxdyn Error这样的服务器入口而是会被编译为 wasm 并作为模块入口导出的函数配合wasm-bindgen由 Trunk 处理。依赖与构建优化Cargo.toml 解读[package] name counter version 0.1.0 edition 2021 [profile.release] opt-level z codegen-units 1 lto true [dependencies] leptos { path ../../leptos, features [csr] } console_log 1.0 log 0.4.22 console_error_panic_hook 0.1.7 gloo-timers { version 0.3.0, features [futures] } [dev-dependencies] wasm-bindgen 0.2.93 wasm-bindgen-test 0.3.42 web-sys 0.3.70leptos { path ../../leptos, features [csr] }以仓库内路径依赖当前主线 leptos并开启csrfeature——它决定了本应用按纯客户端渲染模式编译不包含 SSR/hydration 相关代码路径opt-level z、codegen-units 1、lto true针对 wasm 体积与性能的发布优化z以体积优先优化、单 codegen unit 配合全量 LTO 允许跨 crate 内联显著减小最终 wasm 体积并提升运行性能gloo-timers提供set_timeout等定时器能力带 futures feature示例依赖中保留它便于演示异步能力dev-dependencieswasm-bindgen、wasm-bindgen-test、web-sys用于在浏览器里做 DOM 测试。浏览器内测试wasm-bindgen-test 实战tests/web.rs展示了如何在真实浏览器里验证组件行为。测试使用wasm_bindgen_test_configure!(run_in_browser)让测试跑在浏览器环境而不是 node并通过wasm-bindgen-test提供的#[wasm_bindgen_test]宏声明异步测试。clear 测试的核心流程创建测试容器section并挂到document.body用mount_to(test_wrapper, || view! { SimpleCounter initial_value10 step1/ })渲染初始值为 10 的计数器注意这里用的是 mount.rs 中的mount_to可挂载到任意元素用query_selector(button)拿到 Clear 按钮并click()调用tick().await让响应式系统完成一轮微任务刷新注释明确说明响应式建立在异步系统之上DOM 不会同步更新必须让 effect 跑完用outer_html()/inner_html()与用signal(0)重新渲染的期望视图对比验证点击后值归零。inc 测试则演示了更朴素的 DOM 操作方式通过first_child()/next_sibling()遍历按钮与文本节点连点 1 两次后断言text.text_content() Value: 2!连点 −1 四次后断言Value: -2!再点 Clear 断言Value: 0!。其中还展示了一个实用的测试技巧用signal(n)构造期望文本、再.into_view().build().outer_html()生成对比 HTML——注释指出into_view()在这里只是使用常规 DOM 渲染器的便捷写法视图是惰性的build()才会真正创建 DOM 元素并返回ElementState。运行与验证# 进入示例目录 cd examples/counter # 启动 Trunk 开发服务器并自动打开浏览器 trunk serve --open # 如需运行浏览器内测试以 wasm-bindgen-test 方式 # 需要先为 wasm32-unknown-unknown 目标安装测试 runner如 wasm-bindgen-test-runner打开页面后你将看到四个元素Clear、−1、Value: 0!、1。点击 1 文本实时变为Value: 1!连续点击 −1 变为负数点击 Clear 立即归零。整个过程中没有页面刷新——所有状态变更都由 leptos 响应式信号驱动最终以最小 DOM 更新的方式同步到视图。小结examples/counter虽然只有几十行代码却完整覆盖了 leptos 开发的核心链路#[component]组件定义与属性传参、signal响应式状态、view!模板与事件绑定、CSR 模式下的入口挂载以及基于wasm-bindgen-test的真实浏览器 DOM 测试。以此为起点你可以沿着仓库中的 examples/README.md 继续探索其他示例如counter_isomorphic、counter_without_macros、todo_app_sqlite等把同样的组件与响应式模式扩展到 SSR、路由、服务端函数等更复杂场景。【免费下载链接】leptosBuild fast web applications with Rust.项目地址: https://gitcode.com/GitHub_Trending/le/leptos创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表