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界面交互的更多相关文章
- iBox v2.0 发布,Web化仿iOS7界面/交互的JavaScirpt库
iBox2 是一个仿 iOS 7 界面/交互的 JavaScirpt 库,它运行在 webkit 内核的移动浏览器之上,依赖 iScroll5,帮助开发者构建更接近 iOS 体验的 WebApp. 伴 ...
- 基于MVC4+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出
数据的导入导出,在很多系统里面都比较常见,这个导入导出的操作,在Winform里面比较容易实现,我曾经在之前的一篇文章<Winform开发框架之通用数据导入导出操作>介绍了在Winform ...
- 基于MVC4+EasyUI的Web开发框架经验总结(2)- 使用EasyUI的树控件构建Web界面
最近花了不少时间在重构和进一步提炼我的Web开发框架上,力求在用户体验和界面设计方面,和Winform开发框架保持一致,而在Web上,我主要采用EasyUI的前端界面处理技术,走MVC的技术路线,在重 ...
- 【云计算】Docker集中化web界面管理平台shipyard
Docker集中化web界面管理平台shipyard docker shipyard seanlook 2015年01月05日发布 ...
- OpenWRT - WEB界面开发思路和基本方法
想要对OpenWRT的WEB界面(*下称界面)进行修改.修改的目标是: 1.修改页面的样式,设计为企业的风格(stylesheet) 2.新建自己的功能,实现 访问页面后,用户就可以对配置文件(也就是 ...
- web界面设计
本书描述了6个设计原理,即直截了当.简化交互.足不出户.提供邀请.使用变换.即时反应. 一.直截了当(alan cooper:"在哪里输出,就要允许在哪里输入") 1.1 行内编辑 ...
- Web界面设计(Designing Web Interfaces中文版) (美)斯科特 pdf扫描版
Web界面设计是由Bill Scott编著.电子工业出版社出版的一部图书,在Web已经进入崭新的时代的今天,界面的设计显得非常重要,本书就是基于独一无二的Web环境下.在创建丰富体验的过程中设计Web ...
- AngularJs与Java Web服务器交互
AngularJs是Google工程师研发的产品,它的强大之处不是几句话就能描述的,只有真正使用过的人才能体会到,笔者准备在这篇文章中,以一个简单的登录校验的例子说明如何使用AngularJs和Web ...
- 5.PHP与Web页面交互
PHP与Web页面交互 PHP中提供了两种与Web页面交互的方法,一种是通过Web表单提交数据,另一种是通过URL参数传递. 表单提交用户名字和密码: <form name "form ...
- CheungSSH国产自动化运维工具开源Web界面
CheungSSH web2.0 发布文档 CheungSSH 简介 CheungSSH是一款国人自主研发的Linux运维自动化管理服务器软件,秉着为企业降低运营成本,解放管理员双手和自动化生产的理念 ...
随机推荐
- NC22596 Rinne Loves Data Structure
题目链接 题目 题目描述 Rinne 喜欢 OI.在 9102 年的 PION 中,她在初赛遇到了这样一道题目: 阅读下列代码,然后回答问题. 补充:建树过程中会更新lc和rc,这实质上是一个二叉查找 ...
- Python中用With open as 实现对文件的操作
with open as f在Python中用来读写文件(夹). 基本写法如下: with open(文件名,模式)as f: f.write(内容)#写操作 例:with open ('这个文章.t ...
- 使用BP神经网络实现函数逼近
1 一元函数逼近 1.1 待逼近函数 1.2 代码 clear,clc p=[-4:0.1:4]; %神经网络输入值 t=sin(0.5*pi*p)+sin(pi*p); %神经网络目标值 n=15; ...
- KQL笔记
KQL: {'query': {'bool': {'must': [{'match': {'Sql': 'insert'}}, {'match': {'PolicyName.keyword': 'd8 ...
- spring boot读取json文件并实现接口查询
0.源码下载 https://download.csdn.net/download/IndexMan/84238085 1.说明 最近需要在spring boot项目启动时读取json文件并保存到Li ...
- 简单了解HTTP、Websocket和Netty
前言 伴随着网络的快速发展,网络通讯越来越重要,通讯的快捷.安全.方便影响着用户的体验.本文将探讨这些技术的原理.特点以及在实际应用中的应用场景. 1.HTTTP(超文本传输协议) HTTP是一种传输 ...
- requests请求超时尝试重连的3种方式
参考文档 https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html#module-urllib3.util.retry ...
- 扣子(coze.cn)| 由浅入深,手把手带你实现Java转型学习助手
扣子(coze.cn)是一款用来开发新一代 AI Chat Bot 的应用编辑平台,无论你是否有编程基础,都可以通过这个平台来快速创建各种类型的 Chat Bot,并将其发布到各类社交平台和通讯软件上 ...
- 【Azure 应用服务】查看App Service for Linux上部署PHP 7.4 和 8.0时,所使用的WEB服务器是什么?
问题描述 如何查看PHP应用部署到App Service后,Azure上面使用的应用服务器是什么呢?因为App Service支持两种操作系统,Windows 和 Linux.在Windows中,使用 ...
- 基于 BDD 理论的 Nebula 集成测试框架重构(下篇)
本文首发于 Nebula Graph 公众号 NebulaGraphCommunity,Follow 看大厂图数据库技术实践. 在上篇文章中,我们介绍了 Nebula Graph 的集成测试的演进过程 ...