2个版本
0.5.1 | 2020年5月9日 |
---|---|
0.5.0 | 2020年5月9日 |
#23 in #wasm-framework
用于 savory-html
16KB
88 行
用户界面构建库
TODO:添加README内容
lib.rs
:
Savory是用于构建用户界面的库。
特性
- 视图:视图可以是任何实现
View
特质的类型或任何返回Node
的独立函数,视图可以是特质的对象,这使得它们非常可组合。 - 元素:Savory在构建有状态的UI时使用元素作为核心构建单元。元素拥有自己的状态并通过消息处理用户输入。
- UI元素集合:Savory附带了一系列可重用和可主题化的UI元素。
- 主题:UI元素可以通过实现
ThemeImpl
特质的任何类型进行主题化,主题完全控制元素的外观。 - 类型化HTML:使用类型化的CSS和HTML属性,Savory努力不在创建CSS和HTML属性时依赖字符串,因为这些可能导致难以调试的错误。
- 增强Seed API:对Seed API的增强,使得使用
Node
和Orders
变得有趣。
Savory试图使编写UI元素变得有趣且无需样板代码。
Savory包
savory
:Savory CLIsavory-core
:构建用户界面的库(此包)savory-html
:Savory的类型化HTMLsavory-elements
:基于Savory的UI元素savory-derive
:辅助派生
核心概念
Savory 有两种主要类型:视图 和 元素,视图类型生成静态 HTML,而元素类型生成交互式 HTML,就是这样。
元素类型必须实现 Element
和 View
特性,这将使它们具有交互性。
视图类型必须实现 View
特性,这将生成静态 HTML。
反例
这里有一个非常简单的计数器,它没有使用 Savory 的所有功能,但对于初学者来说是一个好的起点。
use savory_core::prelude::*;
use savory_html::prelude::*;
use wasm_bindgen::prelude::*;
// app element (the model)
pub struct Counter(i32);
// app message
pub enum Msg {
Increment,
Decrement,
}
impl Element for Counter {
type Message = Msg;
type Config = Url;
// initialize the app in this function
fn init(_: Url, _: &mut impl Orders<Msg>) -> Self {
Self(0)
}
// handle app messages
fn update(&mut self, msg: Msg, _: &mut impl Orders<Msg>) {
match msg {
Msg::Increment => self.0 += 1,
Msg::Decrement => self.0 -= 1,
}
}
}
impl View<Node<Msg>> for Counter {
// view the app
fn view(&self) -> Node<Msg> {
let inc_btn = html::button().add("Increment").on_click(|_| Msg::Increment);
let dec_btn = html::button().add("Decrement").on_click(|_| Msg::Decrement);
html::div()
.add(inc_btn)
.add(self.0.to_string())
.add(dec_btn)
}
}
#[wasm_bindgen(start)]
pub fn view() {
// mount and start the app at `app` element
Counter::start();
}
依赖项
~17MB
~295K SLoC