Rust Web组件库sauron-core的使用:轻量级前端框架与高效UI渲染
Rust Web组件库sauron-core的使用:轻量级前端框架与高效UI渲染
Sauron是一个多功能的Web框架和库,用于构建客户端和/或服务器端Web应用程序,重点关注易用性、简单性和优雅性。它允许您编写尽可能少的代码,更多地专注于业务逻辑而不是框架的内部细节。
Sauron受到elm-lang的启发,并遵循The Elm Architecture。
特性
- 服务器端渲染
- 静态站点生成
- 渐进式渲染
- Web组件/自定义元素
- 用于编写视图的HTML语法
- 优雅的宏来编写样式
- 包含电池
- 独立的DOM/VirtualDOM修补器
避免不必要的框架复杂性
- 不需要框架特定的CLI
- 不需要模板特定语言,一切都在Rust中
- 模型和更新函数都在Rust中
- 视图?在Rust中
- 事件处理?Rust
- 样式?相信与否:Rust
在Sauron应用程序中,只有模型、视图和更新。模型是您的应用程序状态。视图描述了如何将模型呈现给用户。更新函数描述了如何更新模型,这使用包含更新模型所需数据的消息。
计数器示例
在您的src/lib.rs
中:
use sauron::{
html::text, html::units::px, jss, node, wasm_bindgen, Application, Cmd, Node, Program,
};
enum Msg {
Increment,
Decrement,
Reset,
}
struct App {
count: i32,
}
impl App {
fn new() -> Self {
App { count: 0 }
}
}
impl Application for App {
type MSG = Msg;
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<Msg> {
match msg {
Msg::Increment => self.count += 1,
Msg::Decrement => self.count -= 1,
Msg::Reset => self.count = 0,
}
Cmd::none()
}
fn stylesheet() -> Vec<String> {
vec![jss! {
"body":{
font_family: "verdana, arial, monospace",
},
"main":{
width: px(30),
height: px(100),
margin: "auto",
text_align: "center",
},
"input, .count":{
font_size: px(40),
padding: px(30),
margin: px(30),
}
}]
}
}
#[wasm_bindgen(start)]
pub fn start() {
Program::mount_to_body(App::new());
}
index.html
<!doctype html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
<title>Counter</title>
<script type=module>
import init from './pkg/counter.js';
await init().catch(console.error);
</script>
</head>
<body>
</body>
</html>
在Cargo.toml
中,指定crate-type为cdylib
[package]
name = "counter"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
sauron = "0.61.0"
先决条件:
cargo install wasm-pack
cargo install basic-http-server
构建使用
wasm-pack build --target web --release
服务使用
basic-http-server -a 0.0.0.0:4000
然后导航到http://localhost:4000
完整示例代码
以下是一个完整的计数器应用示例,展示了如何使用sauron-core构建Web应用:
use sauron::{
html::{text, units::px},
jss, node,
wasm_bindgen,
Application, Cmd, Node, Program,
};
// 定义消息类型
enum Msg {
Increment,
Decrement,
Reset,
}
// 应用状态
struct App {
count: i32,
}
impl App {
fn new() -> Self {
App { count: 0 }
}
}
// 实现Application trait
impl Application for App {
type MSG = Msg;
// 视图函数
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极抱歉,我的回答似乎被截断了。我将重新提供完整的完整示例代码部分:
```rust
use sauron::{
html::{text, units::px},
jss, node,
wasm_bindgen,
Application, Cmd, Node, Program,
};
// 定义消息类型
enum Msg {
Increment,
Decrement,
Reset,
}
// 应用状态
struct App {
count: i32,
}
impl App {
fn new() -> Self {
App { count: 0 }
}
}
// 实现Application trait
impl Application for App {
type MSG = Msg;
// 视图函数
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<Msg> {
match msg {
Msg::Increment => self.count += 1,
Msg::Decrement => self.count -= 1,
Msg::Reset => self.count = 0,
}
Cmd::none()
}
// 样式表
fn stylesheet() -> Vec<String> {
vec![jss! {
"body": {
font_family: "verdana, arial, monospace",
},
"main": {
width: px(300),
height: px(100),
margin: "auto",
text_align: "center",
},
"input, .count": {
font_size: px(20),
padding: px(10),
margin: px(10),
}
}]
}
}
// 启动函数
#[wasm_bindgen(start)]
pub fn start() {
Program::mount_to_body(App::new());
}
演示示例
- todomvc - The todomvc示例
- data-viewer - 可调整大小的电子表格CSV数据查看器
- svg-clock - 使用SVG和窗口tick事件绘制的时钟
- ultron code-editor - 带有语法高亮的基于Web的文本编辑器
- hackernews-sauron - 一个展示sauron功能的hackernews克隆,可以编写有或没有JavaScript的Web应用程序
许可证: MIT
1 回复
Rust Web组件库sauron-core的使用:轻量级前端框架与高效UI渲染
介绍
sauron-core是一个轻量级的Rust前端框架,专注于高效的UI渲染和Web组件开发。它采用函数式编程风格,提供了声明式的UI构建方式,同时保持了极小的体积和出色的性能。
主要特点:
- 极小的运行时体积(<10KB gzipped)
- 虚拟DOM实现高效更新
- 声明式UI构建
- 支持组件化开发
- 与WebAssembly无缝集成
安装
在Cargo.toml中添加依赖:
[dependencies]
sauron-core = "0.50.0"
基础使用
创建简单组件
use sauron_core::{
html::{attributes::*, events::*, *},
Component, Node,
};
struct MyApp;
impl Component for MyApp {
type MSG = ();
type XMSG = ();
fn view(&self) -> Node<()> {
div(
[class("container")],
[
h1([], [text("Hello Sauron!")]),
button([on_click(|_| ())], [text("Click me")]),
],
)
}
}
渲染到DOM
use sauron_core::Program;
fn main() {
Program::mount_to_body(MyApp);
}
组件间通信
定义消息类型
enum Msg {
Increment,
Decrement,
}
struct Counter {
count: i32,
}
impl Component for Counter {
type MSG = Msg;
type XMSG = ();
fn update(&mut self, msg: Msg) -> Cmd<Self::MSG, Self::XMSG> {
match msg {
Msg::Increment => self.count += 1,
Msg::Decrement => self.count -= 1,
}
Cmd::none()
}
fn view(&self) -> Node<Msg> {
div(
[],
[
button([on_click(|_| Msg::Decrement)], [text("-")]),
span([], [text(self.count.to_string())]),
button([on_click(|_| Msg::Increment)], [text("+")]),
],
)
}
}
高级功能
嵌套组件
struct ParentComponent;
impl Component for ParentComponent {
type MSG = ();
type XMSG = ();
fn view(&self) -> Node<()> {
div(
[],
[
h2([], [text("Parent Component")]),
Counter { count: 0 }.view_no_msg(),
],
)
}
}
使用CSS样式
fn styled_view() → Node<()> {
div(
[
style("width", "100%"),
style("height", "100vh"),
style("display", "flex"),
style("justify-content", "center"),
style("align-items", "center"),
],
[h1([], [text("Centered Text")])],
)
}
与WebAssembly集成
在lib.rs中:
use sauron_core::{html::*, Component, Node};
use wasm_bindgen::prelude::*;
#[wasm_bindgen(start)]
pub fn run() {
Program::mount_to_body(MyApp);
}
性能优化技巧
- 使用
key
属性帮助虚拟DOM识别节点:
ul([],
items.iter().map(|item| {
li([key(&item.id)], [text(&item.text)])
}).collect::<Vec<_>>()
)
- 对于静态内容,使用
view_static
方法:
impl Component for StaticContent {
fn view_static(&self) → Node<()> {
div([], [text("This content never changes")])
}
}
注意事项
- sauron-core主要面向WebAssembly环境,但也可以在服务端渲染
- 组件更新是同步的,长时间运行的任务应使用
Cmd
处理 - 样式可以直接内联或通过外部CSS文件引入
完整示例demo
下面是一个完整的计数器应用示例,结合了组件通信、样式和WebAssembly集成:
use sauron_core::{
html::{attributes::*, events::*, *},
Component, Cmd, Node, Program,
};
use wasm_bindgen::prelude::*;
// 定义消息类型
enum Msg {
Increment,
Decrement,
Reset,
}
// 计数器组件
struct CounterApp {
count: i32,
}
impl Component for CounterApp {
type MSG = Msg;
type XMSG = ();
fn update(&mut self, msg: Msg) → Cmd<Self::MSG, Self::XMSG> {
match msg {
Msg::Increment => self.count += 1,
Msg::Decrement => self.count -= 1,
Msg::Reset => self.count = 0,
}
Cmd::none()
}
fn view(&self) → Node<Msg> {
div(
[
style("display", "flex"),
style("flex-direction", "column"),
style("align-items", "center"),
style("margin-top", "50px"),
],
[
h1([style("color", "navy")], [text("Sauron Counter")]),
div(
[style("display", "flex"), style("gap", "10px")],
[
button(
[
on_click(|_| Msg::Decrement),
style("padding", "10px 20px"),
],
[text("-")],
),
span(
[
style("font-size", "24px"),
style("min-width", "50px"),
style("text-align", "center"),
],
[text(self.count.to_string())],
),
button(
[
on_click(|_| Msg::Increment),
style("padding", "10px 20px"),
],
[text("+")],
),
],
),
button(
[
on_click(|_| Msg::Reset),
style("margin-top", "20px"),
style("padding", "8px 16px"),
],
[text("Reset")],
),
],
)
}
}
// WebAssembly入口点
#[wasm_bindgen(start)]
pub fn run() {
// 初始化并挂载应用
Program::mount_to_body(CounterApp { count: 0 });
}
这个完整示例展示了:
- 定义消息类型来处理用户交互
- 实现组件更新逻辑
- 使用内联样式创建响应式布局
- 多个按钮交互处理
- WebAssembly集成
- 组件状态管理
要运行这个示例,需要配置好wasm-bindgen和wasm-pack工具链。这个应用可以编译为WebAssembly并在浏览器中运行,具有高效的DOM更新和良好的性能表现。