Rust如何使用Sauron实现Web界面交互
作者:二次元攻城狮
简介
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:
cargo install wasm-pack
执行以下命令安装basic-http-server:
cargo install basic-http-server
wasm-pack 默认会使用 wasm-opt 工具进行大小优化,而这个工具也是运行时下载安装的。下载 wasm-opt 使用的是 github 链接,国内环境大概率是下载失败的,可以参考 如何安装WASM-OPT? 手动下载 wasm-opt.exe 后放到 .cargo\bin路径下。
创建项目
创建一个名为 hello 的新项目:
cargo new --lib hello
在 Cargo.toml 中指定这个 crate 需要编译为 cdylib(动态系统库):
[lib] crate-type = ["cdylib"]
执行以下命令,添加sauron作为项目的依赖项。
cargo add sauron
编译库文件
修改 src/lib.rs代码,在段落中显示“hello”文本:
use sauron::{node, wasm_bindgen, Application, Cmd, Node, Program}; struct App; impl Application<()> for App { fn view(&self) -> Node<()> { node! { <p> "hello" </p> } } fn update(&mut self, _msg: ()) -> Cmd<Self, ()> { Cmd::none() } } //函数应该在加载 wasm 模块时自动启动,类似于 main 函数 #[wasm_bindgen(start)] pub fn main() { Program::mount_to_body(App::new()); }
- view 方法中使用 node! 宏,采用类似 html 的语法来显示应用程序。
- 为 App 实现 Application 特征,实现必要的方法来告诉 sauron 应用程序的行为。
- 这里的 main 函数在加载 wasm 模块时自动启动,函数可以任意命名,只要配置 start 即可。
执行以下命令进行编译:
wasm-pack build --release --target=web
编译时间稍微有点长,wasm-pack 会在项目中创建一个文件夹 ./pkg,里面包含生成的编译文件,只需要关注其中 2 个文件:
hello.js hello_bg.wasm
它们的名称派生自给定的包名称 <package_name>.js 和 <package_name>_bg.wasm。
引用库文件
在项目的根目录中创建 index.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> </head> <body> <script type=module> import init from './pkg/hello.js'; await init().catch(console.error); </script> </body> </html>
- 使用的是 <script type=module>, 从 ./pkg 文件夹中引用了 ./pkg/hello.js 。
- 在后台,./pkg/hello.js 将负责在后台加载 ./pkg/hello_bg.wasm。
运行项目
重新编译webapp,每次对 rust 代码进行更改时发出此命令。
wasm-pack build --release --target=web
最后使用 basic-http-server 提供文件:
basic-http-server
默认情况下,它在端口 4000 中提供页面,导航到 http://127.0.0.1:4000 以查看“hello”消息。
界面交互示例
在浏览器中显示 3 个按钮,单击这些按钮可以增加/减少和重置计数。
创建项目
创建一个名为 counter 的新 rust 库项目:
cargo new --lib counter
接下来修改 crate 类型为 “cdylib” 库 ,添加 sauron 依赖,这里不在赘述。
编译库文件
在 src/lib.rs 中放入此代码:
use sauron::prelude::*; use sauron::node; struct App { count: i32, } //添加了一个函数 new 来创建以 count 0 开头的初始状态 App impl App { fn new() -> Self { App { count: 0 } } }
定义应用程序将具有的一组操作:
enum Msg { Increment, Decrement, Reset, }
为模型 App 实现 Application 特征:
impl Application<Msg> for App { fn view(&self) -> Node<Msg> { node! { <main> <input type="button" value="+" on_click=|_| { Msg::Increment } /> <button class="count" on_click=|_|{Msg::Reset} >{text(self.count)}</button> <input type="button" value="-" on_click=|_| { Msg::Decrement } /> </main> } } fn update(&mut self, msg: Msg) -> Cmd<Self, Msg> { match msg { Msg::Increment => self.count += 1, Msg::Decrement => self.count -= 1, Msg::Reset => self.count = 0, } Cmd::none() } }
- view 方法返回类型为 Node<Msg>,这意味着它创建一个 html 节点,其中它的任何成员 html 元素都有一个事件侦听器,该事件侦听器可以向程序处理程序发出 Msg 消息。
- update 方法接受 Msg 作为参数,并根据 Msg 的变体修改模型 App。
实现应用函数
接下来为 wasm Web 应用定义入口点,通过使用 #[wasm_bindgen(start)] 注释公共函数来完成:
#[wasm_bindgen(start)] pub fn start() { Program::mount_to_body(App::new()); }
为了演示纯函数交互,这里再添加一个简单的加法函数:
#[wasm_bindgen] pub fn add(a: i32, b: i32) -> i32 { a + b }
如果只需要js调用Rust的函数,那只需要添加 wasm_bindgen 依赖即可,参考 使用Rust和WebAssembly整花活儿(一)——快速开始。
引用库文件
在项目基本文件夹的 index.html 文件中链接应用,可以像往常一样放置样式:
<html> <head> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"/> <title>Counter</title> <style type="text/css"> body { font-family: verdana, arial, monospace; } main { width:30px; height: 100px; margin:auto; text-align: center; } input, .count{ font-size: 40px; padding: 30px; margin: 30px; } </style> <script type=module> import init, { add } from './pkg/counter.js'; await init().catch(console.error); const result = add(1, 2); console.log(`the result from rust is: ${result}`); </script> </head> <body> </body> </html>
注意上面的 import init, { add } from ,add 函数在使用前需要导入,否则会调用失败。
运行项目
编译库文件:
wasm-pack build --release --target=web
启动静态站点:
basic-http-server
访问 http://127.0.0.1:4000 查看效果:
参考资料
到此这篇关于Rust使用Sauron实现Web界面交互的文章就介绍到这了,更多相关Rust Web界面交互内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!