经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Rust » 查看文章
Rust使用Sauron实现Web界面交互
来源:cnblogs  作者:二次元攻城狮  时间:2024/3/26 8:59:50  对本文有异议

简介

Sauron 是一个多功能的 Web 框架和库,用于构建客户端和/或服务器端 Web 应用程序,重点关注人体工程学、简单性和优雅性。这使您可以编写尽可能少的代码,并更多地关注业务逻辑而不是框架的内部细节。
github:https://github.com/ivanceras/sauron
文档:https://sauron-rs.github.io/

架构

Sauron 遵循模型-视图-更新架构(也称为 Elm 架构),它总是分为三个部分:

  • 模型 - 应用程序的状态
  • 视图 - 一种将状态转换为 HTML 的方法
  • 更新 - 一种根据消息更新状态的方法

Application 和组件

为了使模型在 Sauron 程序中运行,它必须实现 Application trait,然后定义下面两个函数:

  • view 函数:该函数告诉程序如何显示模型。
  • update 函数:该函数描述如何根据消息更新模型状态。

简单入门示例

先决条件

确保已安装所有必备组件:

  • rust and cargo:Rust基础环境和工具。
  • wasm-pack:将 rust 代码编译到 webassembly 中,然后放入 ./pkg 目录中。
  • basic-http-server:在本地提供静态文件。

执行以下命令安装wasm-pack

  1. cargo install wasm-pack

执行以下命令安装basic-http-server

  1. cargo install basic-http-server

wasm-pack 默认会使用 wasm-opt 工具进行大小优化,而这个工具也是运行时下载安装的。下载 wasm-opt 使用的是 github 链接,国内环境大概率是下载失败的,可以参考 如何安装WASM-OPT? 手动下载 wasm-opt.exe 后放到 .cargo\bin路径下。

创建项目

创建一个名为 hello 的新项目:

  1. cargo new --lib hello

在 Cargo.toml 中指定这个 crate 需要编译为 cdylib动态系统库):

  1. [lib]
  2. crate-type = ["cdylib"]

执行以下命令,添加sauron作为项目的依赖项。

  1. cargo add sauron

编译库文件

修改 src/lib.rs代码,在段落中显示“hello”文本:

  1. use sauron::{node, wasm_bindgen, Application, Cmd, Node, Program};
  2. struct App;
  3. impl Application<()> for App {
  4. fn view(&self) -> Node<()> {
  5. node! {
  6. <p>
  7. "hello"
  8. </p>
  9. }
  10. }
  11. fn update(&mut self, _msg: ()) -> Cmd<Self, ()> {
  12. Cmd::none()
  13. }
  14. }
  15. //函数应该在加载 wasm 模块时自动启动,类似于 main 函数
  16. #[wasm_bindgen(start)]
  17. pub fn main() {
  18. Program::mount_to_body(App::new());
  19. }
  • view 方法中使用 node! 宏,采用类似 html 的语法来显示应用程序。
  • 为 App 实现 Application 特征,实现必要的方法来告诉 sauron 应用程序的行为。
  • 这里的 main 函数在加载 wasm 模块时自动启动,函数可以任意命名,只要配置 start 即可。

执行以下命令进行编译:

  1. wasm-pack build --release --target=web

编译时间稍微有点长,wasm-pack 会在项目中创建一个文件夹 ./pkg,里面包含生成的编译文件,只需要关注其中 2 个文件:

  1. hello.js
  2. hello_bg.wasm

它们的名称派生自给定的包名称 <package_name>.js<package_name>_bg.wasm

引用库文件

在项目的根目录中创建 index.html:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1" />
  6. </head>
  7. <body>
  8. <script type=module>
  9. import init from './pkg/hello.js';
  10. await init().catch(console.error);
  11. </script>
  12. </body>
  13. </html>
  • 使用的是 <script type=module>, 从 ./pkg 文件夹中引用了 ./pkg/hello.js
  • 在后台,./pkg/hello.js 将负责在后台加载 ./pkg/hello_bg.wasm

运行项目

重新编译webapp,每次对 rust 代码进行更改时发出此命令。

  1. wasm-pack build --release --target=web

最后使用 basic-http-server 提供文件:

  1. basic-http-server

默认情况下,它在端口 4000 中提供页面,导航到 http://127.0.0.1:4000 以查看“hello”消息。

界面交互示例

在浏览器中显示 3 个按钮,单击这些按钮可以增加/减少和重置计数。

创建项目

创建一个名为 counter 的新 rust 库项目:

  1. cargo new --lib counter

接下来修改 crate 类型为 “cdylib” 库 ,添加 sauron 依赖,这里不在赘述。

编译库文件

在 src/lib.rs 中放入此代码:

  1. use sauron::prelude::*;
  2. use sauron::node;
  3. struct App {
  4. count: i32,
  5. }
  6. //添加了一个函数 new 来创建以 count 0 开头的初始状态 App
  7. impl App {
  8. fn new() -> Self {
  9. App { count: 0 }
  10. }
  11. }

定义应用程序将具有的一组操作:

  1. enum Msg {
  2. Increment,
  3. Decrement,
  4. Reset,
  5. }

为模型 App 实现 Application 特征:

  1. impl Application<Msg> for App {
  2. fn view(&self) -> Node<Msg> {
  3. node! {
  4. <main>
  5. <input type="button"
  6. value="+"
  7. on_click=|_| {
  8. Msg::Increment
  9. }
  10. />
  11. <button class="count" on_click=|_|{Msg::Reset} >{text(self.count)}</button>
  12. <input type="button"
  13. value="-"
  14. on_click=|_| {
  15. Msg::Decrement
  16. }
  17. />
  18. </main>
  19. }
  20. }
  21. fn update(&mut self, msg: Msg) -> Cmd<Self, Msg> {
  22. match msg {
  23. Msg::Increment => self.count += 1,
  24. Msg::Decrement => self.count -= 1,
  25. Msg::Reset => self.count = 0,
  26. }
  27. Cmd::none()
  28. }
  29. }
  • view 方法返回类型为 Node<Msg>,这意味着它创建一个 html 节点,其中它的任何成员 html 元素都有一个事件侦听器,该事件侦听器可以向程序处理程序发出 Msg 消息
  • update 方法接受 Msg 作为参数,并根据 Msg 的变体修改模型 App。

实现应用函数

接下来为 wasm Web 应用定义入口点,通过使用 #[wasm_bindgen(start)] 注释公共函数来完成:

  1. #[wasm_bindgen(start)]
  2. pub fn start() {
  3. Program::mount_to_body(App::new());
  4. }

为了演示纯函数交互,这里再添加一个简单的加法函数:

  1. #[wasm_bindgen]
  2. pub fn add(a: i32, b: i32) -> i32 {
  3. a + b
  4. }

如果只需要js调用Rust的函数,那只需要添加 wasm_bindgen 依赖即可,参考 使用Rust和WebAssembly整花活儿(一)——快速开始

引用库文件

在项目基本文件夹的 index.html 文件中链接应用,可以像往常一样放置样式:

  1. <html>
  2. <head>
  3. <meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
  4. <title>Counter</title>
  5. <style type="text/css">
  6. body { font-family: verdana, arial, monospace; }
  7. main {
  8. width:30px;
  9. height: 100px;
  10. margin:auto;
  11. text-align: center;
  12. }
  13. input, .count{
  14. font-size: 40px;
  15. padding: 30px;
  16. margin: 30px;
  17. }
  18. </style>
  19. <script type=module>
  20. import init, { add } from './pkg/counter.js';
  21. await init().catch(console.error);
  22. const result = add(1, 2);
  23. console.log(`the result from rust is: ${result}`);
  24. </script>
  25. </head>
  26. <body>
  27. </body>
  28. </html>

注意上面的 import init, { add } from ,add 函数在使用前需要导入,否则会调用失败。

运行项目

编译库文件:

  1. wasm-pack build --release --target=web

启动静态站点:

  1. basic-http-server

访问 http://127.0.0.1:4000 查看效果:
image

参考资料

原文链接:https://www.cnblogs.com/timefiles/p/18094312

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号