2个版本

0.5.1 2020年5月9日
0.5.0 2020年5月9日

#23 in #wasm-framework


用于 savory-html

MIT/Apache

16KB
88

用户界面构建库

TODO:添加README内容


lib.rs:

Savory是用于构建用户界面的库。

master docs · crate info · pipeline · rustc version · unsafe forbidden

特性

  • 视图:视图可以是任何实现View特质的类型或任何返回Node的独立函数,视图可以是特质的对象,这使得它们非常可组合。
  • 元素:Savory在构建有状态的UI时使用元素作为核心构建单元。元素拥有自己的状态并通过消息处理用户输入。
  • UI元素集合:Savory附带了一系列可重用和可主题化的UI元素。
  • 主题:UI元素可以通过实现ThemeImpl特质的任何类型进行主题化,主题完全控制元素的外观。
  • 类型化HTML:使用类型化的CSS和HTML属性,Savory努力不在创建CSS和HTML属性时依赖字符串,因为这些可能导致难以调试的错误。
  • 增强Seed API:对Seed API的增强,使得使用NodeOrders变得有趣。

Savory试图使编写UI元素变得有趣且无需样板代码。

Savory包

核心概念

Savory 有两种主要类型:视图元素,视图类型生成静态 HTML,而元素类型生成交互式 HTML,就是这样。

元素类型必须实现 ElementView 特性,这将使它们具有交互性。

视图类型必须实现 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